![](/img/trans.png)
[英]Is there a way to make match.call + eval combination work when called from a function?
[英]match.call called in wrong environment when eval’ing
我嘗試使用以下語義實現一個函數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
,外部用於評估實際表達式,而inner用於評估參數。
不幸的是,后一種評估發生在錯誤的背景下。 當嘗試使用檢查當前幀的函數調用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
究竟是如何評估的? 為什么這不起作用? 而且, 我該如何使這項工作?
這個重寫會解決你的問題嗎?
let <- function (expr, ...) {
expr <- match.call(expand.dots = FALSE)$expr
given <- list(...)
eval(expr, list2env(given, parent = parent.frame()))
}
let(x = 1, y = 2, x + y)
# [1] 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.