let
次のセマンティクスで関数を実装してみました:
> let(x = 1, y = 2, x + y)
[1] 3
substitute
…の構文と概念的に似ていますwith
。
次のコードはほとんど機能します (上記のインスタンスの呼び出しは機能します)。
let <- function (...) {
args <- match.call(expand.dots = FALSE)$`...`
expr <- args[[length(args)]]
eval(expr,
list2env(lapply(args[-length(args)], eval), parent = parent.frame()))
}
ネストさeval
れた 、実際の式を評価する外側、および引数を評価する内側に注意してください。
残念ながら、後者の評価は間違ったコンテキストで行われます。let
これは、次のような現在のフレームを調べる関数で呼び出そうとすると明らかになりますmatch.call
。
> (function () let(x = match.call(), x))()
Error in match.call() :
unable to find a closure from within which 'match.call' was called
の評価環境として親フレームを提供することを考えましeval
たが、うまくいきません:
let <- function (...) {
args <- match.call(expand.dots = FALSE)$`...`
expr <- args[[length(args)]]
parent <- parent.frame()
eval(expr,
list2env(lapply(args[-length(args)], function(x) eval(x, parent)),
parent = parent)
}
これにより、同じエラーが発生します。どのように正確にmatch.call
評価されますか? なぜこれが機能しないのですか?そして、どうすればこれを機能させることができますか?