Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

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()を使いましょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした