とかかれているのをふと見かけてなるほどなあと思ったのでメモ。
# formulas automatically capture their enclosing environment foo <- function(x) { y <- 10 ~ x + y }
(https://github.com/hadley/rlang/blob/84a63a1a660cebff373b9db02ac37e04c934dbde/R/tidy-eval.R#L30-L34)
※rlangはlazyevalの後継のパッケージ
f <- foo(1) f #> ~x + y #> <environment: 0x000000001b36db90>
と、このオブジェクトを表示しただけではy
に値は入っていない。でもy
の値はその環境に保存されているので、
lazyeval::f_eval(f) #> [1] 11
という感じになる。
ちょっと変更して、この環境にアクセスする裏口的な関数increase_y()
というのをつくってみる。
bar <- function(x) { y <- 10 increase_y <<- function() {y <<- y+1} ~ x + y }
これを呼び出すとbar()
でできたformulaが捕捉している環境のy
の値が変わっているのがわかる。
b <- bar(1) lazyeval::f_eval(b) #> [1] 11 increase_y() lazyeval::f_eval(b) #> [1] 12
考えてみれば当たり前な気もするけど、クロージャよりお手軽に環境を捕捉できるのすごい。便利。
結局いろいろやろうと思うとその環境を操作する手段を用意しないといけないのでそんなことないかも。