2016-03-02 95 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

相關問題