When debugging functions calling other functions in many levels using the browser, it is often hard to know what level to enter on for inspecting a particular variable. It is cryptic when the functions contain apply
, sapply
, lapply
calls producing intermediate levels. Is there a way to search for a variable by name on all levels of the stack?
Let's say I have the functions below, producing an error in f3
. I would assume that when entering on level 5 I should be able to list the contents of any environment above the one I am currently in, using the pos
or envir
argument in some way, but I can't figure out how. How can I for instance look for v2
?
f1 <- function(){
v1 <- 1
sapply(1:3, f2)
}
f2 <- function(...){
v2 <- 2
f3()
}
f3 <- function(){
v3 <- 3
stop("Oh no!")
}
> options(error=recover)
> f1()
Error in f3() : Oh no!
Enter a frame number, or 0 to exit
1: f1()
2: #3: sapply(1:3, f2)
3: lapply(X = X, FUN = FUN, ...)
4: FUN(1:3[[1]], ...)
5: #3: f3()
You obtain the callstack in a list
with sys.frames
. In this case, if you call sys.frames
after the browser
starts, you'll get a list
of length 9. Frames 6-9 include the call that raised the error and the calls involved in starting the browser
(you can see this by calling sys.calls
). The first five frames are the ones displayed in the call stack that recover
prints. Once the browser
starts, you can look at the namespace of each level of the callstack in your example with
lapply(sys.frames()[1:5], ls)
or search for the frame containing the variable with
which(sapply(sys.frames(), function(frame) 'v2' %in% ls(frame)))
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