我编写了一个使用match.call
的函数,它在我直接调用函数时起作用,但是,当函数在另一个函数中调用时它会中断。我认为它与match.call
如何处理环境有关,但我无法弄明白。这是一个可重复的例子:
tester <- function() {
var <- "helloworld"
myFunc(var)
}
myFunc <- function(x) {
tmp <- match.call()
tmp[[1]] <- quote(toupper)
eval(tmp)
}
tester() # error
myFunc("helloworld") # works fine
我相信在myFunc
内调用tester
时,它无法找到var
,因为它存在于tester
函数的隔离环境中。
有关如何让myFunc
在tester
内工作的任何想法都将不胜感激。我尝试更改eval
和match.call
的环境,但无济于事。
答案 0 :(得分:5)
你的怀疑是完全正确的。
非常简单的解决方案是在父项的上下文中评估函数:将eval
替换为eval.parent
。
myFunc <- function(x) {
tmp <- match.call()
tmp[[1]] <- quote(toupper)
eval.parent(tmp)
}
通常,函数traceback
可以极大地帮助调试类似的问题:
> tester()
Error in as.character(x) :
cannot coerce type 'closure' to vector of type 'character'
好的,但是我们在讨论“闭包”(=功能)?
> traceback()
5: toupper(x = var)
4: eval(expr, envir, enclos)
3: eval(tmp) at #5
2: myFunc(var) at #5
1: tester()
第一行有线索:toupper(x = var)
。在tester
的上下文中,var
指的是函数(闭包)stats::var
,因为它的包附加了。