【发布时间】:2015-11-06 09:19:01
【问题描述】:
在函数中,我们如何才能可靠地返回包含函数本身的对象?
例如:
functionBuilder <- function(wordToSay) {
function(otherWordToSay) {
print(wordToSay)
print(otherWordToSay)
get(as.character(match.call()[[1]]))
}
}
我可以像这样构建一个函数:
functionToRun <- functionBuilder("hello nested world")
...并运行它...
functionToRun("A")
#[1] "hello nested world"
#[1] "A"
#
#function(otherWordToSay) {
# print(wordToSay)
# print(otherWordToSay)
# get(as.character(match.call()[[1]]))
# }
#<environment: 0x1e313678>
... 如您所见,functionToRun 返回自身。但是,如果我通过 sapply 调用 functionToRun,这种方法似乎会中断:
> sapply(LETTERS, functionToRun)
#[1] "hello nested world"
#[1] "A"
#Error in get(as.character(match.call()[[1]])) : object 'FUN' not found
我可以看到这是因为使用 sapply 时的实际调用是 FUN 但 FUN 在 pos = -1 时不存在(get 的默认值)。在该位置工作的代码如下所示:
get(as.character(match.call()[[1]]),envir = sys.frame(sys.parent()))
但是如果没有通过 sapply 调用该函数,则相同的代码将失败,因为 sys.frame(sys.parent())) 回退太远,最终引用了 R_GlobalEnv。
从文档 (R 3.2.2) 中,我预计 dynGet 可能会解决仅根据需要返回堆栈的问题。虽然这适用于函数的sapply 调用,但当函数被单独调用时它会失败。 (此外,它被标记为“有点实验性”)。相反,getAnywhere 似乎很有希望,但似乎不适用于 sapply 调用函数。
是否有可靠的方法来返回当前正在处理的函数,即适用于裸函数调用和 sapply 包装函数调用?
我现在正在做的是将获取函数的尝试包装在 tryCatch 中;但我有点不确定我是否可以相信get(as.character(match.call()[[1]]),envir = sys.frame(sys.parent())) 将适用于所有包装案例(不仅仅是 sapply)。所以,我正在寻找一种更合理的方法来解决这个问题。
可能相关的问题:
【问题讨论】:
标签: r