Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

move up a frame, debug R environment

Tags:

r

debugging

frame

When debugging a function, I would like to move up to the parent frame and look at some variables there. How do I do this?

Here is a sample:

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

I then debug both functions using debug("g") and debug("f"). When I end up in g at the Browser>, I would like to move back up to f to examine x.

Thanks

like image 204
Alex Avatar asked Mar 21 '12 00:03

Alex


3 Answers

You can use recover (it is often used to debug code after an actual error, via options(error=utils::recover), but it can be called directly).

> 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]> 
like image 180
Vincent Zoonekynd Avatar answered Nov 09 '22 11:11

Vincent Zoonekynd


In R terminology, you are wanting to investigate the parent frame of g()'s evaluation environment (i.e. the environment in which g was called). The functions for doing that are documented in the help page for ?sys.parent.

Once your browser indicates that you are 'debugging in g(x + 1)', you can do the following. (Thanks to Joshua Ulrich for suggesting where to help locate ones position in the call stack .)

# 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: To understand the collection of functions described in ?sys.parent, it's probably worth noting that parent.frame() is (basically) shorthand for sys.frame(sys.parent(1)). If you find yourself in an evaluation environment farther down a call stack (as revealed by where, for instance), you can reach into environments farther back up the call stack (say two steps up) by either parent.frame(2) or sys.frame(sys.parent(2)).

like image 32
Josh O'Brien Avatar answered Nov 09 '22 11:11

Josh O'Brien


Just call on.exit(browser()) when browsing f's body and you'll return back to it after you're done with g()

See output copied from the console below :

> f <- function() {
+   x <-1
+   g(x+1)
+ }
> g <- function(z) {
+   y = z+2
+   return(y)
+ }
> debug("f")
> debug("g")
> f()
debugging in: f()
debug at #1: {
    x <- 1
    g(x + 1)
}
Browse[2]> on.exit(browser()) # browser() will be run in this environment just before we exit
Browse[2]> 
debug at #2: x <- 1
Browse[2]> 
debug at #3: g(x + 1)
Browse[2]> 
debugging in: g(x + 1)
debug at #1: {
    y = z + 2
    return(y)
}
Browse[3]> 
debug at #2: y = z + 2
Browse[3]> 
debug at #3: return(y)
Browse[3]> 
exiting from: g(x + 1)
Browse[2]> x # we're back to f so we can investigate x
[1] 1
Browse[2]> 
exiting from: f()
[1] 4
like image 32
Moody_Mudskipper Avatar answered Nov 09 '22 11:11

Moody_Mudskipper