GNU R は JavaScript や Common Lisp と同様に Lexical scope との事。
特殊な代入演算子「<<-」または「->>」を用いると、親環境の変数に対して代入ができる。
未定義の変数を参照すると自動的に親環境の変数を参照するが、
代入はローカル変数を自動的に生成するため、以降は親環境の変数がマスクされてしまう。
ローカル変数と同名の外側環境の変数にアクセスしたい場合は get()、assgin() の envir にターゲットの環境を渡して参照や代入を行う。
parent.env(env) で親環境にアクセスできるんだけど、env が省略できない。
現在の環境は environment() で取得できるので、これを与える。
.GlobalEnv または globalenv() でグローバル環境が得られる。
f1 = function() {
f2 = function(y) {
print(c("f2", x)) # parent (1st is global (#3), 2nd is parent (#2))
x <<- y # parent (1st is global (#3), 2nd is parent (#2))
x = 3 # local (#1)
print(c("f2.parent.parent", get("x", envir=parent.env(parent.env(environment()))))) # global (#3)
print(c("f2.parent", get("x", envir=parent.env(environment())))) # parent (1st is global (#3), 2nd is parent (#2))
print(c("f2", get("x", envir=environment()))) # local (#1)
}
f2(10) # 10 is assigned to global (#3) : 1st
print(c("f1", x)) # parent = global (#3)
x = 2 # local (#2)
f2(100) # 100 is assigned to local (#2) : 2nd
print(c("f1", x)) # local (#2)
}
> remove(x)
> f1()
Error in print(c("f2", x)) : object 'x' not found
> x=1 # global (#3)
> f1()
[1] "f2" "1"
[1] "f2.parent.parent" "10"
[1] "f2.parent" "10"
[1] "f2" "3"
[1] "f1" "10"
[1] "f2" "2"
[1] "f2.parent.parent" "10"
[1] "f2.parent" "100"
[1] "f2" "3"
[1] "f1" "100"
> x # global (#3)
[1] 10
という事で、親環境の変数ではなく、グローバル変数を直に叩きたいなら以下のように get() や assign() の envir にグローバル環境を与える。
get("変数名", envir=.GlobalEnv)
assign("変数名", 値, envir=.GlobalEnv)
変数ではなく変数名を文字列として与える点に注意。
参考:
- An Introduction to R / 10.7 Scope