• Stars
    star
    134
  • Rank 270,967 (Top 6 %)
  • Language
    R
  • Created almost 4 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Debugging Tools to Inspect the Intermediate Steps of a Call

R-CMD-check

boomer

The {boomer} package provides debugging tools that let you inspect the intermediate results of a call. The output looks as if we explode a call into its parts hence the name.

  • boom() prints the intermediate results of a call or a code chunk.
  • rig() creates a copy of a function which will display the intermediate results of all the calls of it body.
  • rig_in_namespace() rigs a namespaced function in place, so its always verbose even when called by other existing functions. It is especially handy for package development.

Installation

Install CRAN version with:

install.packages("boomer")

Or development version with:

remotes::install_github("moodymudskipper/boomer")

boom()

library(boomer)
boom(1 + !1 * 2)

boom(subset(head(mtcars, 2), qsec > 17))

You can use boom() with {magrittr} pipes or base R pipes: just pipe to boom() at the end of a pipe chain.

library(magrittr)
mtcars %>%
  head(2) %>%
  subset(qsec > 17) %>%
  boom()

If a call fails, {boomer} will print intermediate outputs up to the occurrence of the error, it can help with debugging:

"tomato" %>%
  substr(1, 3) %>%
  toupper() %>%
  sqrt() %>%
  boom()

boom() features optional arguments :

  • clock: set to TRUE to see how long each step (in isolation!) took to run.

  • print: set to a function such as str to change what is printed (see ?boom to see how to print differently depending on class). Useful alternatives would be dplyr::glimpse of invisible (to print nothing).

One use case is when the output is too long.

boom(lapply(head(cars), sqrt), clock = TRUE, print = str)

boom() also works works on loops and multi-line expression.

 boom(for(i in 1:3) paste0(i, "!"))

rig()

rig() a function in order to boom() its body, its arguments are printed by default when they’re evaluated.

hello <- function(x) {
  if(!is.character(x) | length(x) != 1) {
    stop("`x` should be a string")
  }
  paste0("Hello ", x, "!")
}
rig(hello)("world")

rig_in_namespace()

rig() creates a copy of a function, but when developing a package we might want to rig a function in place so it has a verbose output when called by other functions. For this we can use rig_in_namespace().

For instance you might have these functions in a package :

cylinder_vol <- function(r, h) {
  h * disk_area(r)
}

disk_area <- function(r) {
  pi * r^2
}

cylinder_vol depends on disk_area, call devtools::load_all() then rig_in_namespace() on both and enjoy the detailed output:

devtools::load_all()
rig_in_namespace(cylinder_vol, disk_area)
cylinder_vol(3,10)

boom_on() and boom_off()

While debugging a function, call boom_on() and all subsequent calls will be boomed, call boom_off() to return to standard debugging.

boom_shinyApp()

A very experimental feature that allows you to rig the reactives of a shiny app. See vignette("shiny", "boomer") for more information.

For the following app, saved in a proper project/package:

histogramUI <- function(id) {
  tagList(
    selectInput(NS(id, "var"), "Variable", choices = names(mtcars)),
    numericInput(NS(id, "bins"), "bins", value = 10, min = 1),
    plotOutput(NS(id, "hist"))
  )
}

histogramServer <- function(id) {
  moduleServer(id, function(input, output, session) {
    data <- reactive(mtcars[[input$var]])
    output$hist <- renderPlot({
      hist(data(), breaks = input$bins, main = input$var)
    }, res = 96)
  })
}

ui <- fluidPage(
  histogramUI("hist1")
)
server <- function(input, output, session) {
  histogramServer("hist1")
}

The output of boom_shinyApp(ui, server) will look like:

There will be issues, please report!

Addin

To avoid typing boom() all the time you can use the provided addin named β€œExplode a call with boom()”: just attribute a key combination to it (I use ctrl+shift+alt+B on windows), select the call you’d like to explode and fire away!

Options

Several options are proposed to weak he printed output of {boomer}’s functions and addin, see ?boomer to learn about them.

In particular on some operating systems {boomer}’s functions’ output might not always look good in markdown report or reprexes. It’s due to how he system handles UTF-8 characters. In this case one can use options(boomer.safe_print = TRUE) for a more satisfactory input.

Notes

{boomer} prints the output of intermediate steps as they are executed, and thus doesn’t say anything about what isn’t executed, it is in contrast with functions like lobstr::ast() which return the parse tree.

Thanks to @data_question for suggesting the name {boomer} on twitter.

More Repositories

1

flow

View and Browse Code Using Flow Diagrams
R
397
star
2

typed

Support Types for Variables, Arguments, and Return Values
R
159
star
3

unglue

Extract matched substrings using a pattern, similar to what package glue does in reverse
R
158
star
4

powerjoin

Extensions of 'dplyr' and 'fuzzyjoin' Join Functions
R
99
star
5

fastpipe

A fast pipe implementation
R
85
star
6

nakedpipe

Pipe Into a Sequence of Calls Without Repeating the Pipe Symbol.
R
69
star
7

burglr

Copy Functions from Other Packages Without Adding Them As Dependencies
R
58
star
8

refactor

Tools for Refactoring Code
R
56
star
9

safejoin

Wrappers around dplyr functions to join safely using various checks
R
42
star
10

opt

Set Options Conveniently
R
40
star
11

reactibble

Use Dynamic Columns in Data Frames
R
40
star
12

inops

Infix Operators for Detection, Subsetting and Replacement
R
40
star
13

myverse

Easily Load a Set of Packages
R
26
star
14

boom

Print the Output of Intermediate Steps of a Call
R
23
star
15

devtag

Restrict Help Files to Development
R
20
star
16

pipediff

Show Diffs Between Piped Steps
R
20
star
17

doubt

Enable operators containing the '?' symbol
R
18
star
18

dotdot

Enhanced assignments. Use `..` on the right hand side as a shorthand for the left hand side.
R
17
star
19

qplyr

Delayed Evaluation With tidyverse Verbs
R
16
star
20

elephant

make variables remember their history
R
15
star
21

tricks

An Addin to Easily Program and Trigger Actions
R
14
star
22

tibbleprint

Print Data Frames Like Tibbles
R
14
star
23

ggframe

data frames that print as ggplots
R
14
star
24

tag

Build function operator factories supporting the tag$function(args) notation
R
13
star
25

editor

Edit scripts programatically
R
13
star
26

datasearch

Find Datasets Observing Specific Conditions
R
13
star
27

once

A Collection of Single Use Function Operators
R
11
star
28

pkg

Package Objects
R
10
star
29

ask

ask R anything
R
10
star
30

intercept

Intercept Messages and Warnings Based on Class, Package or Regular Expression
R
10
star
31

blame

Semantic Version Control for R
R
9
star
32

recycle

Set Hook on Garbage Collection
R
9
star
33

ggfail

A Quick And Dirty Package to Make Wrong ggplot Calls Fail
R
8
star
34

cutr

Enhanced cut And Useful Related Functions
R
8
star
35

tags

A collection of tags built using the package tag
R
8
star
36

now

Remove Exported Functions Depending On Lifecycle
R
7
star
37

liblog

Log Calls to loadNamespace
R
7
star
38

woof

wadlo's companion package
R
7
star
39

ggdollar

Use nested lists of functions to set ggplot theme attributes intuitively
R
7
star
40

shootnloot

Easily share objects between remote sessions
R
7
star
41

goto

What the Package Does (One Line, Title Case)
R
6
star
42

midi

What the Package Does (Title Case)
R
6
star
43

mmpipe

Not maintained, use *pipes* instead : https://github.com/moodymudskipper/pipes which has a cleaner implementation (and a few differences)
R
6
star
44

shinycheck

Check shiny Code
R
5
star
45

loop

Alternatives to apply Functions
R
5
star
46

withDT

Use data.table Syntax For One Call
R
4
star
47

replace

Replace Variable Names in R Scripts
R
4
star
48

ghstudio

Experimental tools to use git/github with RStudio
R
4
star
49

dot3

Tools to Manipulate the Ellipsis Object
R
3
star
50

devtag.example

An example using 'devtag'
R
3
star
51

tidygm

Music as Tidy Data Frames
R
3
star
52

flat

Flatten package to script you can source to recover the package
R
2
star
53

adventofcode2021

My Solutions for Advent Of Code 2021
R
2
star
54

github.traffic

What the Package Does (One Line, Title Case)
R
2
star
55

bigbrothr

Provide Automated Feedback to Package Maintainers on the usage of their package.
R
2
star
56

tabs

Extends rstudioapi
R
1
star
57

debugverse

Brainstorming ideas for debugging workflow and tools, not a package (yet ?)
1
star
58

docalltest

Some alternative to do.call and a comparison
R
1
star
59

check

Readable Assertions
R
1
star
60

flexaddins

What the Package Does (One Line, Title Case)
1
star
61

debugonce

Rstudio Addin to debugonce without typing
R
1
star
62

adventofcode2020

My Solutions for Advent Of Code 2020
R
1
star
63

tidyversediagrams

What the Package Does (One Line, Title Case)
R
1
star
64

private

private closures for closures
R
1
star
65

selfbm

Benchmark a Function against Itself
R
1
star
66

pbfor

RETIRED, use {once} instead! https://github.com/moodymudskipper/once
R
1
star
67

poof.tricks

What the Package Does (One Line, Title Case)
R
1
star
68

frankenply

Avoid Using Functionals by Prefixing your Arguments Directly in the Function Call
R
1
star
69

realquick

One line object summaries
1
star
70

pivot

Pivot Inside 'summarize' Calls
R
1
star
71

alt.doc

Alternative help files.
R
1
star
72

easydb

DBI and dplyr wrappers to write to DB, fetch and run data manipulation operations on server side.
R
1
star