2013-06-23 4 views
6

Sto provando a scrivere una funzione che cattura gli argomenti della funzione da cui è chiamato. Ad esempio,ottenendo gli argomenti di una funzione genitore in R, con nomi

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() purtroppo non aggiunge i nomi dei parametri match con valori degli argomenti, e mi piacerebbe scrivere una versione simile di get_args che restituisce un risultato simile al

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

$x 
[1] 1 

$y 
[1] 2 

$z 
[1] 3 

sostituire "get_args()" con "match.call()" direttamente non è la soluzione che sto cercando, poiché in realtà get_args farà alcune altre cose prima di restituire gli argomenti delle sue funzioni genitore.

Ho provato a utilizzare match.call() con sys.parent() in diversi modi, ma non riesco a ottenere la funzione per restituire gli argomenti del chiamante; restituisce solo gli argomenti di get_args().

C'è un modo per rendere get_args() restituisce l'output identico a quello del chiamante2 per il caso di test sopra riportato? So che nominare gli argomenti manualmente è possibile usando i formals(), ma è garantito che sia equivoco?

Se sono necessari chiarimenti, lasciare un commento sotto. Grazie.

EDIT 1:

l'obiettivo di get_args() è quello di agire come un modo user-friendly di ottenere gli argomenti con i quali è stato chiamato una funzione. Digitando as.list (match.call()) [- 1] diventa vecchio, ma poiché match.call afferra la funzione chiamata più vicina ottiene solo gli argomenti di get_args() al momento.

get_args() otterrà anche gli argomenti predefiniti dalla funzione padre, ma questo facile da implementare.

SOLUZIONE:

grazie Hong Ooi, la chiave per utilizzare match.call sembra essere fornire sia la chiamata e la definizione della funzione che si desidera scoprire. Un leggermente modificata, la versione anonima-friendly di get_args è inferiore per i posteri

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

} 

Questa versione trova la funzione più in alto lo stack di chiamate, afferra la sua definizione e chiamare, e corrisponde a parametri ai suoi argomenti.

risposta

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] 
} 

La chiave qui è quello di impostare l'argomento definition-match.call essere get_arg 's funzione di chiamata. Questo dovrebbe (si spera!) Funzionare nel caso generale in cui è possibile chiamare get_args da qualsiasi luogo.

+0

risposta interessante, ma sfortunatamente get_args deve essere un argomento a variabile zero. Sono d'accordo in questo modo renderebbe la vita più facile, ma la funzione (anche se con molte modifiche) verrà utilizzata nel codice di produzione per CRAN, che non consentirà chiamate interne. – RyanGrannell

+0

Vedere la mia modifica per rimuovere argomenti da 'get_call'. Non vedo ancora perché sia ​​necessaria una funzione personalizzata. Forse dovresti postare il problema sottostante come una nuova domanda, e le persone possono aiutarti a risolverlo in un modo che non richiede il linguaggio munging. –

+0

punto equo. Ho modificato il mio post originale. – RyanGrannell

Problemi correlati