knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
This article is a short guide to debugging with shinybreakpoint
, i.e. what exactly happens after the breakpoint is set and session is refreshed. If one would like to read more systematically about debugging in {Shiny}
, it should be relatively easy to find many useful articles.
When the file is source()
d or parse()
d, srcref
attribute is added to the functions to indicate where the objects originated^[Murdoch, D. 2010. Source References. The R Journal, pp. 16-19.]. This attribute contains the code (for chosen object) as shown in the file, e.g. with the comments, and also path to the file. Knowing this, it is possible to show to the user location (in the file, not just in the body of function) where the computation stops.
Unfortunately, after the body of function is modified, this attribute is lost. We could now distinguish between the srcref
attribute for function itself and for the body()
of that function and say that attr(fun, "srcref")
is lost, but not attr(body(fun), "srcref")
, but it won't help us very much - we still won't be able to point to the original file when debug mode starts. Some solutions are of course possible to show the 'stop' location in the file - RStudio displays the original file (where browser()
is not visible), but shinybreakpoint
constructs temporary file (in temporary location which exists as long as R session - do not confuse with Shiny session) where the whole added code is visible, separated by two lines of comments - first one indicates where the additional code starts and the second one reminds that this is only temporary file. Temporary file is constructed for each breakpoint. Having the separate file has downsides, of course, but on the other hand it allows to modify the (temporary) file without any fear which could accompany the user when working with original file. Debug mode is not just a mode to read a values, but the possibility to execute any code is a very convenient way to experiment with different solutions.
One way to execute code in the debug mode is just to type this code in the console or move the cursor from one place to another in the file (to copy the line or execute it directly from the editor by Ctrl + Enter shortcut). Another way is to use the shortcuts available in the debug mode (see ?browser
) - like n
to go to the next line or use panel in RStudio with buttons dedicated to debug mode.
In the context of shinybreakpoint
two things should be highlighted. First one is that to exit from debug mode without stopping the app, c
or f
should be used - c
is preferred, because when f
is used, RStudio still displays the debug mode panels even that we are no longer in the debug mode and app runs as usual.
The second one is debugging regular functions. Currently shinybreakpoint
allows to set breakpoint only in the reactive context, but it doesn't mean that regular functions can't be debugging. To do this, breakpoint should be set in the reactive context just before the function call and then in the debug mode is an option to step into function call (s
or dedicated button in the panel).
Generally, in R value can be displayed in two ways: by using print(var)
or just by typing var
in the console (where var
is a variable). Because n
, s
and other shortcuts available during the debug mode are valid variable names, it can happen that indeed variables will have names the same like the shortcuts - in this situation it is needed to use print()
to display value.
However, it can be also the case when the value won't be displayed, no matter which method is used. In case of Shiny applications, it happens when debugging renderPrint
, because the output is captured by the web browser. To be able to display the values, it is necessary to call sink()
in the debug mode and then values can be displayed. When exiting from the debug mode, session is refreshed, so there is no negative consequence of using sink()
.
shinybreakpoint
allows to set only one breakpoint - in case more breakpoints will be set, only the last one will be saved. Additionally, breakpoint is removed after exit from the debug mode - it is necessary, because otherwise we could end up in the infinite loop if breakpoint would be set in reactive context which is run when the app (session) starts - that's because session is refreshed when exiting from debug mode.
There is, however, an example of behavior which could led to the situation when breakpoint seems to be persist. In some web browsers (when breakpoint is hit) app freezes (is in loading state), but this is not always the case - sometimes UI is still available. And then, when some input will change (what will trigger reactive context where breakpoint was set before), user will end up in the debug mode again after closing it. To avoid this, UI shouldn't be used during debug mode.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.