http://qiita.com/items/325bdf48f4f4885a86f1 の続き。
##1-3 環境のイメージ
環境って言うとなんか、かたい感じがして、ちょっととっつきにくいと思う。なんかcall/cc
とか思い出しちゃうし・・・。
なので、環境のイメージは、「おせっかいで親切なおばちゃん」という感じです。
「おばちゃん、きゅうりあるー?」
「あー今ないわー、ちょっと待っててーな、お隣さんに聞いてくるさかいー」
そんな感じいいと思います。
変数についてはこれですべてオーケーだと思います。変数については。
##1-4 関数呼び出しでの環境
こっから格段にややこしくなります。
さっき暗黙のうちに、.GlobalEnv
っていうのが最初に聞く相手だったんですが、いつもそうとは限りません。Rのコンソールでちょいちょいやってる時は、だいたい.GlobalEnv
です。ややこしいのは、関数を呼び出した時です。本当にこっからややこしいです。
最初に聞く相手を知るには、environment()
です。
> environment()
<environment: R_GlobalEnv>
関数呼び出しの時は、こうなります。
> f <- function() {
+ print(environment())
+ }
> f()
<environment: 0x101ab3720>
なんか適当なおばちゃんがボワッと出てきた感じです。実際にそのとおりで、関数呼び出しの時には、環境が一個作られて、それが一番最初に話を聞く相手になります。
このボワッとおばちゃんは、関数を呼び出すたびに毎回作られます。
> f()
<environment: 0x11682e470>
> f()
<environment: 0x11682b278>
毎回違う環境ですね。
##1-5 変数を作る話を忘れてた
すっかり忘れてた。普通の代入(束縛)演算子<-
を使うと、一番最初に話を聞く相手に、その変数を持っといてもらうことになります。
> ls()
[1] "b" "f" "l"
> orz <- 1
> ls()
[1] "b" "f" "l" "orz"
この場合.GlobalEnv
が相手です。
関数呼び出しの時も話は同じで、
> f <- function() {
+ a <- 1
+ print(environment())
+ print(ls(pos = environment()))
+ a
+ }
> f()
<environment: 0x101d90068>
[1] "a"
[1] 1
この関数は最初にa<-1
を実行してます。f()
の呼び出し時の環境(ボワッとおばちゃん)は0x101d...
というやつで、そこにはちゃんとa
があります。
「0x101d...
おばちゃん、ちょっとこのa
もっといてー」
というイメージです。
##1-6 もう少し、関数呼び出しでの環境
関数を呼び出した時に適当に出てきたボワッとおばちゃん環境も、自分が持ってなかったら次の人を紹介してくれるわけですが、それが誰かというと、
> f <- function() {
+ print(parent.env(environment()))
+ }
> f()
<environment: R_GlobalEnv>
この場合は、GlobalEnv
です。この場合は。
で、よく知ってる人にはここでトラップがあります。よくある説明では、
関数の実行環境の親はそれを定義した時の環境となります
的な話があると思います(いみわかんなかったら飛ばしていいです)。
デフォルトではそうなんだけど、ここは正しくなくて、
関数の実行環境の親は関数の環境となります
が正しいです。
つづく。