Prune and call a function with a set arguments

do_call(fcn, args = list(), envir = parent.frame(), prune = FALSE)

Arguments

fcn

A function.

args

A list of arguments passed to the function fcn.

envir

An environment within which to evaluate the call.

prune

If TRUE, the environment stack of fcn is pruned.

Value

Return the value of function call.

See also

Examples

## ------------------------------------------------------------------------
## Example how to avoid huge local objects being part of a local function,
## which might be costly if the function is serialized, e.g. exported
## to a parallel workers
## ------------------------------------------------------------------------

## Report on the 'fcn' size before and after pruning
trace(
  do_call,
  at = 3L, tracer = quote(fcn_size <- size_of(fcn)),
  exit = quote({
    if (prune) {
      message(sprintf("Size of '%s': %s bytes (%s bytes when pruned)",
                      fcn_name, fcn_size, size_of(fcn)))
    } else {
      message(sprintf("Size of '%s': %s bytes",
                      fcn_name, fcn_size))
    }
  }),
  print = FALSE
)
#> Tracing function "do_call" in package "environments"
#> [1] "do_call"

my_fcn <- function(g = NULL, prune = FALSE) {
  cargo <- rnorm(1e6)
  
  n <- 2

  if (is.null(g)) {
    g <- local({
      pi <- 3.14
      function() n * pi
    })
  }

  do_call(g, prune = prune)
}


## Non-pruned function local to a function carries also large 'cargo' object
my_fcn()
#> Size of 'g': 8022932 bytes
#> [1] 6.28

## Pruned function local to a function without large 'cargo' object
my_fcn(prune = TRUE)
#> Size of 'g': 8022932 bytes (22796 bytes when pruned)
#> [1] 6.28


## WARNING: Large objects inside local environments of
##          the function will not the pruned!
g <- local({
  cargo <- rnorm(1e6)
  n <- 2
  local({
    pi <- 3.14
    function() n * pi
  })
})

my_fcn(g)
#> Size of 'g': 8023020 bytes
#> [1] 6.28
my_fcn(g, prune = TRUE)
#> Size of 'g': 8023020 bytes (8020838 bytes when pruned)
#> [1] 6.28

untrace(do_call)
#> Untracing function "do_call" in package "environments"