withr::defer() benefits

  • It has the behaviour we want by default; no extra arguments needed.

  • It works when called in the global environment thanks to deferred_run() and deferred_clear() as the global environment isn’t perishable.

withr::defer(print("hi"))
#> Setting deferred event(s) on global environment.
#>   * Execute (and clear) with `deferred_run()`.
#>   * Clear (without executing) with `deferred_clear()`.

withr::deferred_run()
#> [1] "hi"
  • It lets you pick which function to clean up. This makes it possible to create helper functions.
local_digits <- function(sig_digits, env = parent.frame()) {
  op <- options(digits = sig_digits)
  withr::defer(options(op), env)
}

neater <- function(x, sig_digits) {
  local_digits(1)
  print(x)
}

neater(pi)
#> [1] 3