我試過的功能實現let
具有以下語義時叫錯環境:match.call eval'ing
> 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
究竟如何評估?爲什麼這不起作用?而且,我該如何做這項工作?
可能與此相關的是,從'?match.call':「在函數外部調用'match.call'而不指定'定義'是錯誤。然後嘗試'j < - function(x)x; j(match.call())'看到一個錯誤發生的地方。我沒有把這一切都搞清楚了(並沒有完全弄清楚你真的想做什麼),但是這可能是一個錯誤,它與你使用'match.call()'的奇怪方式非常相似。呼叫一個匿名函數。 – 2013-05-01 14:28:36
@Josh我不認爲它是相關的。錯誤信息是不同的,我稱之爲'match.call'的上下文肯定來自函數中,如果錯誤的話。 – 2013-05-01 14:30:27
我想我暗示的是'match.call()'具有非常獨特的範圍規則,它在C級別變爲特殊的硬連線。 (定義'do_matchcall'的代碼,包括一些有關如何調用它的函數的有趣評論,在'$ R_SRC/src/main/unique.c'中。)與幾乎任何其他函數不同,我不清楚它的評估環境可以通過調用'eval()'來操縱/設置。爲了簡化你的問題,也許首先要弄清楚爲什麼這不起作用(以及如何實現):'j < - function()eval(call(「match.call」)); Ĵ()'。 – 2013-05-01 15:56:21