2015-11-06 49 views
1

在函数内,我们如何可靠地返回包含函数本身的对象?访问函数内被调用的函数

例如有:

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当实际通话FUNFUN根本不存在POS = -1(默认为get)。在这个位置运行的代码看起来像:

get(as.character(match.call()[[1]]),envir = sys.frame(sys.parent()))

但如果功能尚未通过sapply称呼,是因为sys.frame(sys.parent()))走得太远回到相同的代码失败并最终参照R_GlobalEnv

从我预料dynGet或许解决只会早在栈中需要的问题的文件(R 3.2.2)。虽然这适用于函数的调用sapply,但它在自己调用该函数时会失败。 (此外,它被标记为“有点实验性”)。相反getAnywhere似乎很有希望,但似乎不起作用的sapply称为函数。

是否有返回当前正在处理的功能,即一种可靠的方式同时适用于裸露和sapply包裹函数调用?

我在做什么,现在是包装试图抢在tryCatch的功能;但我有点不确定我是否可以相信get(as.character(match.call()[[1]]),envir = sys.frame(sys.parent()))可以在所有包装情况下工作(不仅仅是灌装)。所以,我正在寻找更合理的方法来解决这个问题。

潜在的相关问题:

回答

1

我不能保证,这将适用于所有情况,但它看起来好:

fun <- function(x) { 
    print(x) 
    y <- exp(x) 
    print(y) 
    sys.function(0) 
} 

fun(1) 
# [1] 1 
# [1] 2.718282 
# function(x) { 
# print(x) 
# y <- exp(x) 
# print(y) 
# sys.function(0) 
# } 
lapply(1:5, fun)[[3]] 
# [1] 1 
# [1] 2.718282 
# [1] 2 
# [1] 7.389056 
# [1] 3 
# [1] 20.08554 
# [1] 4 
# [1] 54.59815 
# [1] 5 
# [1] 148.4132 
# function(x) { 
# print(x) 
# y <- exp(x) 
# print(y) 
# sys.function(0) 
# } 

当然,我不明白你需要什么。

+0

我认为这是相当普遍的目的,但我用它来实现类似于'R.cache'的缓存层。所以,我想获得函数本身,以便我可以消化它并将其作为散列的一部分存储函数的结果,以确保缓存的结果与函数当前生成的结果相匹配。 – russellpierce