2014-07-10 21 views
9

C'è un modo per accedere al valore di ritorno di una funzione che viene tracciata da una funzione specificata come parametro di uscita da tracciare? Sembra difficile da capire, ma non sono stato in grado di semplificare la domanda senza perdere le informazioni. Quindi ecco un semplice esempio.Come accedere a un valore di ritorno di una funzione che viene tracciata

abbiamo una semplice funzione di

add10 <- function(a){ 
    a + 10 
} 

E qualche funzione che vogliamo essere chiamato quando chiamata a Add10 uscite.

trace.exit() <- function(){ 
... 
} 

La traccia è impostata nel seguente modo.

trace(add10, exit=trace.exit) 

e facciamo un appello a Add10

add10(5) 

quanto ho capito da ora, saranno chiamati trace.exit dopo add10 terminato l'esecuzione. C'è un modo per accedere al valore di ritorno di add10 all'interno di trace.exit?

Sento che dovrebbe esserci. Ma giocando con sys.frames e guardando attraverso gli ambienti non ero in grado di ottenerlo.

Il motivo è il desiderio di catturare tutte le chiamate per alcune funzioni e restituire i valori che danno.

UPD Soluzione con involucro o qualcosa di simile è bello, ma trace implementa già un motivo decoratore, quindi la mia domanda è su come accedere valore restituito da trace, non di risolvere il problema di decoratori in R.

+0

È difficile vedere dove si nasconde quel valore restituito. In C, i valori alcuni vicini tra loro in [context.c] (https://github.com/wch/r-source/blob/fba3c1b0ac71bb5a681b2c1437ce2a38dfa3bb61/src/main/context.c#L197). Da quello che posso dire, il 'jumpfun' dovrebbe impostare il valore restituito a' val' nel contesto corretto, ma sembra che la funzione 'on.exit' possa essere eseguita in un contesto differente. Speravo che fosse disponibile in ".Last.value", ma sembra non esserlo. Forse è l'interfaccia utente che aggiorna quel valore. – MrFlick

risposta

4

Perché non si usa un wrapper che assegna in modo esplicito il valore restituito a una variabile locale:

add10 <- function(a){ 
    a + 10 
} 

wrap <- function(f) { function(...) { ..ret <- f(...) } } 

add10_wrap <- wrap(add10) 

trace.exit <- function() { 
    cat(sprintf("Return value: %s\n", sys.frame(-1)$..ret)) 
} 

trace(add10_wrap, exit=trace.exit) 

add10_wrap(5) 

uno svantaggio è che il wrapper restituisce sempre risultati invisibili - è per questo che l'esempio precedente stampa solo la forma uscita att.

+0

Grazie, questa è una soluzione perfettamente valida, ma non veramente scalabile. Voglio anche che 'add10' sia chiamabile con lo stesso nome, non con il nome del wrapper. E traccia già dà una soluzione decoratore. Ora mi sto chiedendo se è possibile ottenere il valore di ritorno di accesso in questo. –