LoginSignup
7
8

More than 5 years have passed since last update.

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

Posted at

http://qiita.com/items/325bdf48f4f4885a86f1
http://qiita.com/items/35184390984975ec7c6d の続き。

余談ですが、「環境」という言葉から、ちょっと考えこむと「自分の実行環境はどこか?」しいては「自分が今どの環境の中にいるのか」ということを考えてしまいがちです。これはやめといた方がいいです。

必要なのは、「今自分の隣にいるおばちゃんは誰か」です。これで大分すっきりして気が楽になります。

environment()は、「今自分がどの環境のかなにいるのか教えてくれる関数」ではなくて、「今隣にいるおばちゃんは誰か」を教えてくれる関数です。

1-6 関数の環境

関数は環境を持っています。これは関数呼び出し時に作られる環境とは異なります
「持っています」というのが誤解の元なんだよなあ。

イメージとしては、困ったときに相談するおばちゃんをメモっとく、という感じです。

関数を定義すると、

> f <- function() {
+   print(environment())
+   print(parent.env(environment()))
+ }
> environment(f)
<environment: R_GlobalEnv>

という感じで、fの環境は、この場合は.GlobalEnvです。

> f()
<environment: 0x1169ecb88> #これ呼び出し時に作られたおばちゃん
<environment: R_GlobalEnv> #そのおばちゃんが困ったら相談するおばちゃん

という風に考えると、関数というのは、

  1. 呼び出された時におばちゃん一人つくって、あなたの隣におく。
  2. そのおばちゃんに、困ったときに相談するおばちゃんを教えておく。

という能力を持った人です。

1-7 関数の環境 ≠ 定義時の環境

デフォルトでは、関数の環境、つまり関数がメモったおばちゃんは、関数が定義された時の環境です。

> environment()
<environment: R_GlobalEnv> # 今の環境(あなたの隣のおばちゃん)
> f <- function() {}
> environment(f)
<environment: R_GlobalEnv> # 関数fがメモったのはその環境

> g <- function() {
+   print(environment()) # *1
+   h <- function() {}
+   print(environment(h)) # *2
+ }
> g()
<environment: 0x11726f608> # *1: 今の環境(呼び出し時に作られたやつ)
<environment: 0x11726f608> # *2: 関数hがメモった環境

ただこれ、あとで変えられるんですね。つまり、関数に「困ったらこのおばちゃんに相談するように言っといてねー」ってあとから出来る。

> f <- function() {
+   parent.env(environment()) # 実行時の環境の親を表示(自分の隣にいるおばちゃんの相談相手)
+ }
> environment(f)
<environment: R_GlobalEnv> # デフォルトでは相談相手は.GlobalEnv
> f()
<environment: R_GlobalEnv> # です。
> 
> e <- new.env() # 新しい環境を作成。おばちゃんひとり作ったと思っとけばいい。
> e
<environment: 0x1171ea1f8>
> 
> environment(f) <- e # 「困ったらこのおばちゃんに聞いとけ」メモ
> environment(f)
<environment: 0x1171ea1f8> # 変更されてる
> f()
<environment: 0x1171ea1f8> # こっちも

あーややこしい。

なので、私はこう考えています。

1-8 関数にまつわる3つの環境

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

おばちゃんで言い換えると

  1. 呼び出し時にボワッと作られるおばちゃん
  2. 1.のおばちゃんが困ったときに相談する相手
  3. 関数を持ってるおばちゃん

この3.がまた厄介で、「関数の環境」と「関数のある環境」は異なります。
これが、http://obeautifulcode.com/R/How-R-Searches-And-Finds-Stuff/ のブログの実践と点線、package:hogenamespace:hogeにつながってきます。

つづく。

7
8
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
7
8