2013-06-23 142 views
6

我試圖編寫一個函數來捕獲函數的參數。例如,在R中獲取父函數的參數,名稱爲

get_args <- function() as.list(sys.call(sys.parent()))[-1] 

caller <- function (x, y, z) { 
    get_args() 
} 
caller(1,2,3) 

[[1]] 
[1] 1 

[[2]] 
[1] 2 

[[3]] 
[1] 3 

sys.call()遺憾的是不帶參數值添加匹配參數名稱,我想寫get_args的一個類似的版本,返回類似下面的輸出

caller2 <- function (x, y, z) { 
    as.list(match.call())[-1] 
} 
caller2(1,2,3) 

$x 
[1] 1 

$y 
[1] 2 

$z 
[1] 3 

直接用「match.call()」替換「get_args()」並不是我正在尋找的解決方案,因爲實際上get_args在返回它的父函數參數之前會做一些其他的事情。我試過在sys.parent()中以幾種方式使用match.call(),但是我不能獲得返回調用者參數的函數;它只是返回get_args()的參數。

有沒有什麼辦法讓get_args()返回輸出與上面的測試用例的caller2相同?我知道使用formals()手動命名參數是可能的,但這是保證等價的嗎?

如果需要澄清,請在下面留言。謝謝。

EDIT 1:

get_args的目的()是作爲與獲得其中函數被調用的參數的用戶友好的方式。輸入as.list(match.call())[ - 1]變老,但由於match.call抓取最近的函數調用,它現在只是獲取get_args()的參數。

get_args()也會從父函數獲取默認參數,但這很容易實現。

SOLUTION:

感謝香港大井,關鍵看使用match.call似乎是同時提供呼叫你想了解該函數的定義。稍微修改,get_args匿名的版本下面是爲子孫後代

get_args <- function() { 
as.list(match.call(
    def = sys.function(-1), 
    call = sys.call(-1)))[-1] 

} 

該版本進一步求解函數調用棧,抓住它的定義和調用,以及相匹配的參數及其參數。

回答

8
get_args <- function() 
{ 
    cl <- sys.call(-1) 
    f <- get(as.character(cl[[1]]), mode="function", sys.frame(-2)) 
    cl <- match.call(definition=f, call=cl) 
    as.list(cl)[-1] 
} 

這裏的關鍵是要definition參數設置爲match.callget_arg的調用函數。這應該(希望!)適用於get_args可以從任何地方調用的一般情況。

+0

有意思的答案,但不幸的是get_args必須是一個零變量的參數。我同意這種方式會使生活更輕鬆,但功能(儘管有很多修改)將被用於CRAN的生產代碼,他們不會允許。內部調用。 – RyanGrannell

+0

請參閱我的編輯以從'get_call'中移除參數。我仍然沒有看到爲什麼自定義函數是必要的。也許你應該把潛在的問題作爲一個新問題提出來,人們可以用一種不需要語言轉換的方式來幫助你解決問題。 –

+0

公平點。我編輯了我原來的帖子。 – RyanGrannell