2012-03-21 9 views
14

Quando si esegue il debug di una funzione, vorrei spostarmi al frame principale e osservare alcune variabili lì. Come faccio a fare questo?spostarsi su un frame, eseguire il debug di ambiente R

Ecco un esempio:

f <- function() { 
    x <-1 
    g(x+1) 
} 
g <- function(z) { 
    y = z+2 
    return(y) 
} 

Ho poi il debug entrambe le funzioni utilizzando debug("g") e debug("f"). Quando finisco nello g allo Browser>, vorrei tornare a f per esaminare x.

Grazie

risposta

11

In R terminologia, si vogliono studiare nel frame principale dell'ambiente valutazione g() s'(cioè l'ambiente in cui è stato chiamato g). Le funzioni per farlo sono documentate nella pagina di aiuto per ?sys.parent.

Una volta che il browser indica che si è 'debugging in g(x + 1)', è possibile effettuare quanto segue. (Grazie a Joshua Ulrich per suggerire where per aiutare a localizzare quelle posizione nella stack di chiamate.)

# Confirm that you are where you think you are 
where 
# where 1 at #3: g(x + 1) 
# where 2: f() 

# Get a reference to g()'s parent frame (an environment object) 
pframe <- parent.frame() 
pframe 
# <environment: 0x019b9174> 

# Examine the contents of the parent frame 
ls(env=pframe) 
# [1] "x" 

# Get the value of 'x' in the parent frame 
get("x", env = pframe) 
# [1] 1 

EDIT: Per comprendere la raccolta di funzioni descritte nel ?sys.parent, è probabilmente la pena notare che parent.frame() è (praticamente) abbreviazione di sys.frame(sys.parent(1)). Se ti trovi in ​​un ambiente di valutazione più in basso di uno stack di chiamate (come rivelato da where, ad esempio), puoi raggiungere gli ambienti più lontani dallo stack di chiamate (ad esempio due gradini) da parent.frame(2) o da sys.frame(sys.parent(2)).

+4

Digitando 'where' mentre nel browser sembra che sarebbe utile determinare quanti fotogrammi è necessario andare. –

+0

Grazie a @Joshua per questo suggerimento molto utile. L'ho preso direttamente dal tuo commento e incollato nella parte superiore del blocco di codice. –

+0

Grazie a tutti per le risposte eccellenti. – Alex

24

È possibile utilizzare recover (viene spesso utilizzato per il debug del codice dopo un errore effettivo, via options(error=utils::recover), ma può essere chiamato direttamente).

> f() 
debugging in: g(x + 1) 
debug at #1: { 
    y = z + 2 
    return(y) 
} 
Browse[2]> ls() 
[1] "z" 
Browse[2]> recover() 

Enter a frame number, or 0 to exit 

1: f() 
2: #3: g(x + 1) 

Selection: 1 
Called from: top level 
Browse[3]> ls() 
[1] "x" 
Browse[3]> x 
[1] 1 
Browse[3]> 
+3

Molto interessante. Non mi era mai venuto in mente che 'recover()' potesse essere chiamato in modo interattivo. A volte penso che dovrei semplicemente sedermi e guardare il resto di voi rispondere a tutte le domande, e questo tipo di gemma è esattamente il motivo. –

+1

Grande, grazie per questo .. molto utile. – Alex

Problemi correlati