3

I'd like to create a function prevent_side_effects(expr, envir) that executes expr in environment envir but has read-only access to the variables and functions in envir and all parent environments.

Is locking envir and locking all the symbols therein the only way to do this, or is there a better way? If I go the locking route is it necessary to walk up the graph of parent environments and lock those as well?

Here is a reproducible example that demonstrates how this function would behave:

grandparent.env <- environment()
parent.env <- new.env(parent=grandparent.env)
env <- new.env(parent=parent.env)

env$x <- 1
parent.env$y <- 2
grandparent.env$z <- 3

grandparent.env$f <- function() cat('function defined in grandparent env\n')

out <- prevent_side_effects(envir=env, expr={
    cat(sprintf('%i %i %i\n', x, y, z))
    #> 1 2 3

    f()
    #> function defined in grandparent env

    # The following all throw errors or just define new local variables such 
    # that variables in env, parent.env, and grandparent.env are masked but
    # unchanged.
    x <<- 1000
    y <<- 1000 
    z <<- 1000

    x <- 4
    y <- 5
    z <- 6
    cat(sprintf('%i %i %i\n', x, y, z))
    #> 4 5 6

})

cat(sprintf('%i %i %i\n', x, y, z))
#> 1 2 3
andrew
  • 2,524
  • 2
  • 24
  • 36
  • 2
    If would be nice if you included a [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that we could run to test any possible solutions. – MrFlick Oct 23 '15 at 14:48

0 Answers0