LoginSignup
5
6

More than 5 years have passed since last update.

(Rの)環境問題について その2。

Posted at

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です。この場合は。

で、よく知ってる人にはここでトラップがあります。よくある説明では、

関数の実行環境の親はそれを定義した時の環境となります

的な話があると思います(いみわかんなかったら飛ばしていいです)。

デフォルトではそうなんだけど、ここは正しくなくて、

関数の実行環境の親は関数の環境となります

が正しいです。

つづく。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6