Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging package::function() although lazy evaluation is used

Tags:

r

rstudio

How can I debug efficiently in R if packages are unknown due to lazy evaluation. I would like to keep the basic browser() functionality as it works great - even with the testthat package. As explained in the following post, --with-keep.source is set for my project in "project options => Build Tools".

To reproduce the behavior, create a package TestDebug containing

myfun <- function(a,b) {return(a+b)}

and a script example.R

{
browser()
TestDebug::myfun(1,2)
}

Edit: The situation where TestDebug::myfun(1,2) calls otherpackage::myfun2(1,2) should be also covered. I think the situation should occur in every "real" package?

like image 439
Christoph Avatar asked May 24 '16 15:05

Christoph


People also ask

How do you debug a function in R?

R file corresponding to the code you want to debug, it's easy to use editor breakpoints or browser() to add breakpoints to it. Sometimes, however, you don't have the source file for the code you want to debug. When this is the case, you can set a debug flag on the function you want to debug.

What does calling trace F for function f () do?

Calling trace() on a function allows the user to insert bits of code into a function.

How do I turn off debug in R?

To stop debugging a function, you simply use undebug(logit). If you want to step through a function only once, you can use the function debugonce() instead of debug(). R will go to browser mode the next time the function is called, and only that time — so you don't need to use undebug() to stop debugging.

How do you debug a function?

To debug a function which is defined inside another function, single-step through to the end of its definition, and then call debug on its name. If you want to debug a function not starting at the very beginning, use trace(..., at = *) or setBreakpoint .


1 Answers

The following works for me.

I have my package TestDebug with my function

myfun <- function(a,b) {return(a+b)}

If I run the script

debug(TestDebug::myfun)
TestDebug::myfun(1,2)

The debugger steps right into the source of TestDebug::myfun() not into the :: function as it does when you place a browser() before the call to TestDebug::myfun(1,2).

As you mention in your question: in real-life situations TestDebug::myfun(1,2) often calls otherpackage::myfun2(1,2). If you try to step into otherpackage::myfun2(1,2) you will end up inside the :: function again.

To prevent this I add this functions called inside other functions to the debug index on the fly:

As soon as you are on the line inside TestDebug::myfun() where otherpackage::myfun2(1,2) is called I run debug(otherpackage::myfun2(1,2)) in the console. After that I can step into otherpackage::myfun2(1,2) without problems and end up in the source code of otherpackage::myfun2(1,2). (..and not in the source code of ::)

Don't forget to call undebug(otherpackage::myfun2(1,2)) after you're sure that your problem is not inside otherpackage::myfun2(1,2) to prevent the debugger to jump into otherpackage::myfun2(1,2) the next time it is called.

If you prefer you can also use debugonce(otherpackage::myfun(1,2)) (instead of debug(..)) to only debug a function once.

like image 55
symbolrush Avatar answered Sep 28 '22 13:09

symbolrush