『R言語徹底解説』8章を読んだので、Rの関数に関連する 4 つの環境について理解できたか確認したい。
名前 | 英語 | 調べる方法 |
---|---|---|
エンクロージング環境 | enclosing | environment(f) |
束縛環境 | binding | pryr::where("f") |
実行環境 | execution | environment() |
呼び出し環境 | calling | parent.frame() |
次のような関数を用意する。
R
f <- function() {
cat("x: ", x, "\n")
eclosing_env <- environment(f)
binding_env <- pryr::where("f")
executoin_env <- environment() ; attr(executoin_env, "name") <- "execution_env"
calling_env <- parent.frame()
cat("エンクロージング環境:\t", environmentName(eclosing_env), "\n")
cat("束縛環境:\t\t", environmentName(binding_env), "\n")
cat("実行環境:\t\t", environmentName(executoin_env), "\n")
cat("呼び出し環境:\t", environmentName(calling_env), "\n")
}
これをそのまま呼び出すと、次のような結果になる。
R
x <- 1
f()
結果
x: 1
エンクロージング環境: R_GlobalEnv
束縛環境: R_GlobalEnv
実行環境: execution_env
呼び出し環境: R_GlobalEnv
実行環境以外はグローバル環境である。
エンクロージング環境を変えてみる。
R
enclosing_env <- new.env()
attr(enclosing_env, "name") <- "my_enclosing_env"
assign("x", 999, envir = enclosing_env)
environment(f) <- enclosing_env
f()
結果
x: 999
エンクロージング環境: my_enclosing_env
束縛環境: R_GlobalEnv
実行環境: execution_env
呼び出し環境: R_GlobalEnv
エンクロージング環境を変更できた。
x
の値もグローバル環境の値からエンクロージング環境のものに変わっている。
次に、束縛環境を変えてみる。
R
binding_env <- new.env()
attr(binding_env, "name") <- "my_binding_env"
assign("f", f, envir = binding_env)
parent.env(enclosing_env) <- binding_env
f()
結果
x: 999
エンクロージング環境: my_enclosing_env
束縛環境: my_binding_env
実行環境: execution_env
呼び出し環境: R_GlobalEnv
エンクロージング環境とグローバル環境の間に新しい環境を追加し、そこに f
を置いた。
これは、関数 f()
内で f()
という関数を呼び出そうとすると、呼び出されている関数とは別の、新しく作成した環境にあるものが呼び出されることになる。
さらに、呼び出し環境を変えてみる。
R
f2 <- function() {
calling_env <- environment()
attr(calling_env, "name") <- "my_calling_env"
f()
}
f2()
結果
x: 999
エンクロージング環境: my_enclosing_env
束縛環境: my_binding_env
実行環境: execution_env
呼び出し環境: my_calling_env
関数を呼び出す場所を新しい関数 f2()
の中に変更した。
関数の呼び出し場所を変えれば呼び出し環境は変わる。
R の環境について理解が進んだように思える。