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?
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.
Calling trace() on a function allows the user to insert bits of code into a function.
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.
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 .
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.
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