Skip to Content

Environment chaining in R

In my R development I need to wrap function primitives in proto objects so that a number of arguments can be automatically passed to the functions when the $perform() method of the object is invoked. The function invocation internally happens via do.call(). All is well, except when the function attempts to access variables from the closure within which it is defined. In that case, the function cannot resolve the names.

Here is the smallest example I have found that reproduces the behavior:

library(proto)
 
make_command <- function(operation) {
  proto(
    func = operation,
    perform = function(., ...) {
      func <- with(., func) # unbinds proto method
      do.call(func, list(), envir=environment(operation))
    }  
    )
}
 
test_case <- function() {
  result <- 100  
  make_command(function() result)$perform()
}
 
# Will generate error:
# Error in function ()  : object 'result' not found
test_case()

I have a reproducible testthat test that also outputs a lot of diagnostic output. The diagnostic output has me stumped. By looking up the parent environment chain, my diagnostic code, which lives inside the function, finds and prints the very same variable the function fails to find. See this gist..

How can the environment for do.call be set up correctly?