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
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]>
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)).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With