11  Print debugging

Published

2024-11-06

Warning

The contents for section are under development. Thank you for your patience.

I’ve created the shinypak R package In an effort to make each section accessible and easy to follow:

Install shinypak using pak (or remotes):

# install.packages('pak')
pak::pak('mjfrigaard/shinypak')

Review the chapters in each section:

library(shinypak)
list_apps(regex = 'debug')
## # A tibble: 6 × 2
##   branch                   last_updated       
##   <chr>                    <dttm>             
## 1 10_debugger              2024-12-15 03:02:26
## 2 11_debug-print           2024-11-20 22:09:54
## 3 15_debug-util-funs       2024-09-04 10:06:57
## 4 25.1_debug-selected_vars 2024-01-15 10:29:25
## 5 25.2_debug-var_inputs    2024-01-15 10:25:12
## 6 25.4_debug-print         2024-01-15 10:04:21

Launch the app:

launch(app = "11_debug-print")

Download the app:

get_app(app = "11_debug-print")

In the previous chapter we explored triggering the interactive debugger in Positron with browser() and observe(). In this chapter, we’ll explore another commonly used technique for identifying and resolving issues in code: print debugging.

11.1 Debugging with print()

Print debugging is a different approach than the interactive debugger, and it’s suited for a different types of development workflow. Print debugging involves inserting a print() (or cat()) statement into the body of a function to output variables, values, or other important information at various points.


Using well-placed calls to print() or cat() allows us to display variable values, which helps us to understand the inner-workings of the function. After running the function, we can view the output in the Console (or log file).

11.1.1 Reactive printing

print() and cat() can only provide a snapshot of values or variables at the location and time of the print call, limiting their usefulness in exploring the other parts of the environment or interacting with the running application.

In Shiny apps, a powerful tool for capturing and printing input values is reactiveValuesToList().

reactiveValuesToList(x = , all.names = )

If we combine reactiveValuesToList() with verbatimTextOutput(), and renderPrint(), we can convert Shiny reactive values (i.e., user inputs) into a list that can be printed and displayed back in the UI.

Launch app with the shinypak package:

launch('25.4_debug-print')

Advantages:

  • Simplicity: It’s very easy to implement. Just insert a few lines of code and run the program.

  • Universal: Works in any programming environment, even if sophisticated debugging tools aren’t available.

  • Non-intrusive: It doesn’t require special configurations or debugging tools.

Disadvantages:

  • Limited context: You only see what you explicitly print. If you miss a key variable or condition, you may need to add more print statements.

  • Manual effort: It can be time-consuming to insert, remove, and adjust print statements, especially in large or complex codebases.

  • Clutter: Excessive use of print statements can clutter the code and output.

  • No runtime control: You can’t pause execution or inspect the program state in real-time.

11.2 Recap

If we want to see what’s happening ‘behind the scenes’, we can collect the reactive values and print them in the UI while the app is running.