从函数内部获取函数环境
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
我想在一个环境中定义一个函数,它使用这个环境中的全局变量:
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