从函数内部获取函数环境

Get environment of function from within the function

我想在一个环境中定义一个函数,它使用这个环境中的全局变量:

e <- new.env()
e$a <- 1
e$f <- function() a

## e$f()
## Error in e$f() : object 'a' not found

environment(e$f) <- e
e$f()
# [1] 1

到目前为止一切顺利。现在假设我将另一个(锁定的)绑定添加到 e:

e$b <- 2
lockBinding("b", e)

我如何(暂时)从 f 中解锁此绑定而不使用 使用符号 e

e$f <- function() unlockBinding("b", parent.frame())
environment(e$f) <- e
e$f()

不起作用,因为 parent.frame 没有正确指向 e


我不想直接使用 e 因为这会在我克隆环境时立即中断:

e <- new.env()
e$a <- e$b <- 1
lockBinding("b", e)
e$f <- function() unlockBinding("b", e)
environment(e$f) <- e
## e$b <- 3
## Error in e$b <- 3 : cannot change value of locked binding for 'b'

g <- rlang::env_clone(e)
g$f()
e$b <- 3 ## should not work

好的,找到解决方案:

e$f <- function() unlockBinding("b", parent.env(environment()))

应该可以解决问题。

proto 包促进了这类事情,避免了对环境的最明确的破坏。 proto 对象是具有 class proto 的环境,它有自己的方法。有关详细信息,请参阅包插图。

library(proto)

# create proto object containing 3 objects
p <- proto(a = 1, b = 1, f = function(.) unlockBinding("b", .))

p$lockBinding(sym = "b")  # lock b
p$b <- 3 # error since p$b is locked

p2 <- as.proto(p$as.list()) # clone p
p2$b <- 4 # ok since p2 is distinct from p

p$b <- 3  # as expected, this is an error since p$b is locked

ch <- p$proto() # create a child of p
ch$b  # b is not in ch so it finds it in parent p
## [1] 1

ch$b <- 10  # ok since this creates a new b in ch overriding p$b

p$f() # unlock b
p$b <- 20  # ok