如何完全克隆R6Class Generator

时间:2018-04-18 05:19:04

标签: r r6

我正在开发一个R包并在内部使用R6。我有两个R6对象:

  1. 一个Foo对象,其中包含大量数据和汇总整个数据的方法;
  2. 一个Bar对象,其中包含Foo数据的子集方法以及查询特定子数据的方法。
  3. 我想要做的是创建Bar R6Class Generator对象的克隆并传递包含Foo对象的所有数据的环境。我找不到完成克隆R6Class Generator的方法。

    注意:我不想直接拆分Foo中的数据并将该数据传递给Bar$new,这会大大减慢整个过程的速度,因为很多Bar个对象都会被创造而不是唯一想要的。

    下面是一个简单的例子:

    library(R6)
    
    Foo <- R6Class(classname = "Foo",
        public = list(
            initialize = function (x) {
                private$m_x <- x
                private$m_bar_gen <- private$create_bar_gen(Bar)
            },
    
            new_bar = function () {
                private$m_bar_gen$new()
            }),
    
        private = list(
            m_x = NULL,
            m_bar_gen = NULL,
    
            create_bar_gen = function (Bar) {
                my_bar <- list2env(as.list.environment(Bar), parent = emptyenv())
                class(my_bar) <- "R6Generator"
                my_bar$self <- my_bar
                my_bar$set("private", "m_x", private$m_x, overwrite = TRUE)
                my_bar
            }
        )
    )
    
    Bar <- R6Class(classname = "Bar",
        public = list(
            initialize = function () {
                stopifnot(!is.null(private$m_x))
                private$m_x
            }
        ),
        private = list(
            m_x = NULL
        )
    )
    

    这将在private$m_x未定义

    时停止
    Bar$new()
    #> Error: !is.null(private$m_x) is not TRUE
    

    初始化Foo对象后,

    (foo_1 <- Foo$new(1))
    #> <Foo>
    #>   Public:
    #>     clone: function (deep = FALSE) 
    #>     initialize: function (x) 
    #>     new_bar: function () 
    #>   Private:
    #>     create_bar_gen: function (Bar) 
    #>     m_bar_gen: R6Generator
    #>     m_x: 1
    

    这将起作用

    foo_1$new_bar()
    #> <Bar>
    #>   Public:
    #>     clone: function (deep = FALSE) 
    #>     initialize: function () 
    #>   Private:
    #>     m_x: 1
    

    但原来的Bar R6Class生成器也已更改

    Bar$private_fields$m_x
    #> [1] 1
    

    似乎private$create_bar_gen()无法完成复制R6Class Generator。 my_bar$set将设置原始和新的。

    (foo_2 <- Foo$new(2))
    #> <Foo>
    #>   Public:
    #>     clone: function (deep = FALSE) 
    #>     initialize: function (x) 
    #>     new_bar: function () 
    #>   Private:
    #>     create_bar_gen: function (Bar) 
    #>     m_bar_gen: R6Generator
    #>     m_x: 2
    
    foo_2$new_bar()
    #> <Bar>
    #>   Public:
    #>     clone: function (deep = FALSE) 
    #>     initialize: function () 
    #>   Private:
    #>     m_x: 2
    
    Bar$private_fields$m_x
    #> [1] 2
    
    foo_1$new_bar()
    #> <Bar>
    #>   Public:
    #>     clone: function (deep = FALSE) 
    #>     initialize: function () 
    #>   Private:
    #>     m_x: 2
    

0 个答案:

没有答案