（Rの）環境問題について　その６。


http://qiita.com/items/325bdf48f4f4885a86f1 と
http://qiita.com/items/35184390984975ec7c6d と
http://qiita.com/items/7fdb523a05a2e0b12f35 と
http://qiita.com/items/1cb4a7a05b026a0cf2bb と
http://qiita.com/items/a0a926c9e01aebb6261a の続き。

promiseは後回しにしておいて、名前空間と環境の話をします。

Rはパッケージシステムを用いていて、それぞれのパッケージはそれぞれの名前空間を必ず持っています（確かR 2.14.0 以降）。この話は、パッケージを作成する場合、または既存のパッケージの中の関数をハックしたい場合以外はあんまり役に立ちません。

パッケージ関連の環境のサーチパスと、関数呼び出しでの環境検索は、根っこは同じなんですが、分けて考えたほうがはるかに分かりやすいです。

## 関数にまつわる３つの環境

大事な話なのでもう一度書いておきます。

1. 呼び出し時に作られる環境
2. 呼び出し時に作られる環境の親となる環境
3. 関数がある環境

## 関数呼び出しの時に何が起こるか。

例えば、コンソール上（環境は`.GlobalEnv`）

```R
> environment()
<environment: R_GlobalEnv>
> search()
 [1] ".GlobalEnv"        "tools:RGUI"        "package:stats"     "package:graphics"  "package:grDevices" "package:utils"     "package:datasets"  "package:devtools"  "MacJapanEnv"      
[10] "package:methods"   "Autoloads"         "package:base"     
```

で

```R
> mean(1:3)
```

を実行したときの話を考えます。

1. `.GlobalEnv`で`mean`を探して、なければその親をたどっていく。
2. `package:base`に`mean`を見つける。
3. 適当な環境Xを作って、その親として`mean`の環境をヒモづける。
4. 環境X上で`mean`の中の式を実行する。

## 関数がある環境と関数の環境

サラッと`mean`の環境と書きましたが、これは上の関数にまつわる３つの環境の中の**3**のことで、**関数の環境**です。
関数の環境は`environment()`で、

```R
> environment(mean)
<environment: namespace:base>
```

関数がある場所は`find()`で、

```R
> find("mean")
[1] "package:base"
```

というように調べられます。はい、この二つ、関数がある環境（`package:base`）と関数の環境（`namespace:base`）は異なります。

## 普通の関数のある場所と関数の環境

ちょっとそれますが、`.GlobalEnv`で関数を定義したときは、関数の環境も関数がある環境も両方共`.GlobalEnv`です。
普通は、関数の環境は関数が作られた環境になるので、関数の環境と関数のある環境は一致しますが、これが常に成り立つわけではない、というのは前に説明したとおりです。

## パッケージ内の関数を呼び出したときの変数検索

`mean`の環境は`namespace:base`です。ですので、`mean`を呼び出したときにどういう風に変数を探すかというと、

```R
> debug(mean) # デバッグする
> mean(1:3) # 呼び出す
debugging in: mean(1:3) # デバッガに入る
debug: UseMethod("mean")
Browse[2]> environment() # 今の環境。これは関数呼び出しで適当に作った物
<environment: 0x11903b668>
Browse[2]> parent.env(environment()) # その親。namespace:baseですね。
<environment: namespace:base>
Browse[2]> parent.env(parent.env(environment())) # その親。
<environment: R_GlobalEnv>
Browse[2]> parent.env(parent.env(parent.env(environment()))) # その親。
<environment: 0x101e955c0>
attr(,"name")
[1] "tools:RGUI"
Browse[2]> parent.env(parent.env(parent.env(parent.env(environment())))) # その親
<environment: package:stats>
attr(,"name")
[1] "package:stats"
attr(,"path")
[1] "/Library/Frameworks/R.framework/Versions/2.15/Resources/library/stats"

```

という感じです。

正しく書くと、
1. 関数呼び出しで作られた環境
2. 関数の環境（パッケージの名前空間）
3. .GlobalEnv
4. 以降、`seaerch()`と同じ道をたどる。

となります。実際には、baseパッケージ以外の時は2のあとにbaseパッケージ名前空間が入ります。

面倒なので最後まで環境をたどる関数を定義します。

```R
> f <- function(e = parent.frame()) while (!identical(e, emptyenv())) {print(environmentName(e)); e <- parent.env(e)}
> f()
[1] "R_GlobalEnv"
[1] "tools:RGUI"
[1] "package:stats"
[1] "package:graphics"
[1] "package:grDevices"
[1] "package:utils"
[1] "package:datasets"
[1] "package:devtools"
[1] "MacJapanEnv"
[1] "package:methods"
[1] "Autoloads"
[1] "base"
```

`mean`の呼び出しでは

```R
> debug(mean)
> mean(1)
debugging in: mean(1)
debug: UseMethod("mean")
Browse[2]> f()
[1] "" # これ適当に作られるやつ
[1] "base" # base名前空間
[1] "R_GlobalEnv"
[1] "tools:RGUI"
[1] "package:stats"
[1] "package:graphics"
[1] "package:grDevices"
[1] "package:utils"
[1] "package:datasets"
[1] "package:devtools"
[1] "MacJapanEnv"
[1] "package:methods"
[1] "Autoloads"
[1] "base" # package:base
```

`stats`パッケージの`rnorm`の場合はこうなります

```
rowse[2]> debug(rnorm)
Browse[2]> rnorm(1)
debugging in: rnorm(1)
debug: .Internal(rnorm(n, mean, sd))
Browse[4]> f()
[1] "" # 適当に作られたやつ
[1] "stats" # stats名前空間
[1] "imports:stats" # stats名前空間へのインポート
[1] "base" # base名前空間
[1] "R_GlobalEnv"
[1] "tools:RGUI"
[1] "package:stats"
[1] "package:graphics"
[1] "package:grDevices"
[1] "package:utils"
[1] "package:datasets"
[1] "package:devtools"
[1] "MacJapanEnv"
[1] "package:methods"
[1] "Autoloads"
[1] "base" # package:base
```

という感じです。

インポート？？？

それはまた別の機会に説明します。

つづく・・・