预防R表达的副作用

预防R表达的副作用,r,metaprogramming,side-effects,R,Metaprogramming,Side Effects,我想创建一个函数防止副作用(expr,envir),它在环境envir中执行expr,但对envir和所有父环境中的变量和函数具有只读访问权限 锁定envir并锁定其中的所有符号是唯一的方法,还是有更好的方法?如果我走锁定路线,是否有必要沿着父环境的图表走过去并锁定它们 下面是一个可复制的示例,演示了此函数的行为: grandparent.env <- environment() parent.env <- new.env(parent=grandparent.env) env &l

我想创建一个函数
防止副作用(expr,envir)
,它在环境
envir
中执行
expr
,但对
envir
和所有父环境中的变量和函数具有只读访问权限

锁定
envir
并锁定其中的所有符号是唯一的方法,还是有更好的方法?如果我走锁定路线,是否有必要沿着父环境的图表走过去并锁定它们

下面是一个可复制的示例,演示了此函数的行为:

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

grandparent.env If如果您包含一个示例输入和所需输出,我们可以运行它来测试任何可能的解决方案,那就太好了。