2016-03-02 92 views
0

我使用R6类中的活动绑定来检查赋值给字段之前的值。我想我可以使用闭包来生成如下的绑定,但这不起作用。使用闭包来生成R6绑定

绑定不按照我期望的方式进行评估(根本就是?),因为错误显示了封闭的参数name。我错过了什么?

library(R6) 
library(pryr) 

# pass a field name to create its binding 
generate_binding <- function(name) { 
    function(value) { 
    if (!missing(value) && length(value) > 0) { 
     private$name <- value 
    } 
    private$name 
    } 
} 

bind_x = generate_binding(x_) 
# created as intended: 
unenclose(bind_x) 
# function (value) 
# { 
#  if (!missing(value) && length(value) > 0) { 
#   private$x_ <- value 
#  } 
#  private$x_ 
# } 

MyClass <- R6::R6Class("MyClass", 
    private = list(
    x_ = NULL 
), 
    active = list(
    x = bind_x 
), 
) 

my_class_instance <- MyClass$new() 
my_class_instance$x <- "foo" 
# Error in private$name <- value : 
# cannot add bindings to a locked environment 

回答

3

我认为你误解了闭包的工作方式。 unenclose这里是一条红鲱鱼(因为它实际上并没有告诉你什么是闭包)。封闭包含语句private$name <- value - 它确实不是包含语句private$x_ <- value

通常解决这一问题将是重写闭合,使得未计算的name参数deparsed成它的字符串表示,然后使用子集中的private环境(private[[name]] <- value)。但是,这不起作用,因为R6活动绑定剥离了其封闭环境的关闭。

这是unenclose进来,那么:

MyClass <- R6::R6Class("MyClass", 
    private = list(
    x_ = NULL 
), 
    active = list(
    x = pryr::unenclose(bind_x) 
), 
) 
+0

这是了不起的。谢谢。 – effel

相关问题