LoginSignup
5
5

More than 5 years have passed since last update.

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

Posted at

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

1-9 大事な事なので繰り返します。

関数にまつわる3つの環境とは、

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

です。

普通に使う分には、3は無視していいと思います。1も恒常的なものではないので無視していいと思います。大事なのは関数呼び出しの時の2が何か、を意識しておくことだと思います。

とりあえず関数にまつわる環境の話はこれでいいんだろうか?
なんかよくわかんなかったら教えて下さい。

2 promise

さて、promiseです。これを説明するためには、遅延評価というものを説明する必要があって面倒なんですが、最近見かける話に、

> f <- function(i) function() i
> r <- lapply(1:3, f)
> r[[1]]()
[1] 3
> r[[3]]()
[1] 3

なんでよー、ちらほらってのがあったので、結構ここで引っかかる人は多いみたいです。
上のr[[1]]()がなんで3になるのか即答できる方は読み飛ばしてもらっていいと思います。

2-1 substituteにまつわる誤解

promiseといえばsubstituteです。が、これやるにはcallとかまで行く必要があるので、またこれは別の機会にします。

その代わりにおまけで。

1-10 環境はリスト

環境はリストです。これほんとです。

> environment()
<environment: R_GlobalEnv> # 隣のおばちゃん
> ls()
character(0) # なんも持ってない
> as.list(.GlobalEnv)
named list() # 空リスト
> a <- 1 # a持っといてー
> ls()
[1] "a" # aある。
> as.list(.GlobalEnv) # aのあるリスト
$a
[1] 1

直感的にリストなら要素の追加できるんじゃね?って思います。

> environment()
<environment: R_GlobalEnv>
> ls()
character(0) # なんも持ってない
> .GlobalEnv$b <- 2 # リストの要素bを追加
> ls() 
[1] "b" # あるよ。
> b
[1] 2 # ちゃんとあるよ。

個人的には、関数の中から.GlobalEnvに値を入れる最もいい方法だと思ってるんですが、この方法がいつまでサポートされるかはわからないので、使わないほうがいいと思います。正しくは、

> ls()
character(0)
> assign("b", 2, .GlobalEnv)
> ls()
[1] "b"

という風に、assignで環境を指定して値を束縛するのがR風です。

1-11 <<-.GlobalEnvへの代入ではない、という話

グローバル環境の変数に値を束縛するには<<-を使うというのは巷では有名ですが、これは避けたほうが良いです。X<<-は、隣のおばちゃんにXがあったらそこに、なかったらそのおばちゃんの相談相手に、そこにもなかったらそのおばちゃんの相談相手に、さいごまでなかったら.GlobalEnvに、値を代入する、というものです。

> a <- 1 # グローバル環境のaに1
> a
[1] 1

> e <- new.env() # 環境を作成
> e$a <- 1 # その環境にも変数aをおいとく
> e$a
[1] 1

> f <- function() {
+   a <<- 2 # グローバル環境に2を代入する?
+ }

> environment(f) <- e # fの環境をeにしてから
> f() # fを呼び出し

> a
[1] 1 # グローバルのaは変わってなくて、
> e$a
[1] 2 # eのaが変わってる

という感じになるので、絶対にグローバル環境に入れたければ、assign()を使いましょう。

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