2015-11-06 46 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