9

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評価されますか? なぜこれが機能しないのですか?そして、どうすればこれを機能させることができますか?

4

1 に答える 1