Alex
Alex

Reputation: 19803

browser() debug statement R

I have an R script where I have inserted the following code:

options(Debug=TRUE)
#SOME MORE CODE
browser(expr = isTRUE(getOption("Debug")))
#SOME MORE CODE

After the debugger starts, I would like it to proceed to the next line so I type n. However, this does not proceed to the next line but rather seems to continue.

How do I step through the remainder of my code after a browser() statement?

Thanks

Upvotes: 3

Views: 2561

Answers (2)

Josh O'Brien
Josh O'Brien

Reputation: 162321

To set a point within a function at which to begin debugging, you'll likely want to use trace().

Let's say you have a function myFun and want to begin debugging it right before its call to plot():

myFun <- function() {
    x <- 
        8:1
    y <- 
        1:8
    plot(y~x)
    lines(y~x)
    text(x,y, letters[1:8], pos=3)
}

To construct the call to trace, you will need to know at which step in myFun the call to plot() occurs. To determine that, use the construct as.list(body(myFun)):

as.list(body(myFun)) 
# [[1]]
# `{`
# 
# [[2]]
# x <- 8:1
# 
# [[3]]
# y <- 1:8
# 
# [[4]]
# plot(y ~ x)
# 
# ... More ... 

After noting that the call to plot occurs in step 4, you can use trace() to tell R that you'd like to enter a browser right before step 4 every time myFun is called:

trace(myFun, browser, 4)

# TRY IT OUT
# (Once in the browser, type "n" and press Enter to step through the code.)
myFun()      

Finally, when you're done debugging the function, turn the trace off with a call to untrace(myFun).


EDIT: The strategy for setting breakpoints for sourced-in scripts is similar. Again, you don't actually insert code into the script. Instead use findLineNum() and setBreakPoint().

Let's say that the function myFun() described above is defined in the text file "myScript.R", which has five blank lines before the function definitions. To insert the breakpoint right before the call to plot:

source("myScript.R")            # Must source() once before using findLineNum 
                                # or setBreakPoint
findLineNum("myScript.R#10")    # I see that I missed the step by one line
setBreakpoint("myScript.R#11")  # Insert the breakpoint at the line that calls 
                                # plot()

myFun()                         # Test that breakpoint was properly inserted
                                # (Again, use "n" and Enter to step through code)

Upvotes: 6

Hansi
Hansi

Reputation: 2644

browser() is generally for use when running in interactive mode and used in a sub function because if you have it inline in a script and source the whole thing in it will simply execute the next line against the browser prompt when it is called.

E.g. assuming the script:

options(Debug=TRUE)
browser(expr = isTRUE(getOption("Debug")))
b <- 1 
b <- 2
b <- 3

It would execute like this:

R> options(Debug=TRUE)
R> browser(expr = isTRUE(getOption("Debug")))
Called from: top level 
Browse[1]> b <- 1 
Browse[1]> b <- 2
Browse[1]> b <- 3

If you were to run the script step by step and then call a function as so then it's use makes more sense:

R> options(Debug=TRUE)
R> a <- function() {
 browser(expr = isTRUE(getOption("Debug")))
 b <- 1
 b <- 2
 b <- 3
 return(b)
}
R> e <- a()
Called from: a()
Browse[1]> n
debug at #5: b <- 1
Browse[2]>  # ENTER
debug at #6: b <- 2
Browse[2]> b
[1] 1
Browse[2]>   # ENTER
debug at #7: b <- 3
Browse[2]> b
[1] 2
Browse[2]>   # ENTER
debug at #8: return(b)
Browse[2]> b
[1] 3
Browse[2]>   # ENTER
[1] 3
R> 

Upvotes: 1

Related Questions