2012-10-29 48 views
3

我遇到了一些R参考类的行为,我想解决它。在下面的代码中,引用类B有两个引用类A的字段。参考类内的参考类的实例化 - 锁()和不变性的问题

在B的initialize()方法被调用之前,B中的这些字段似乎被实例化(可能两次),并带有参数类A的零参数(默认)版本。然后在B的初始化过程中用实例A的正确版本替换这些实例。问题是,如果我使用B的实例生成器中的lock(),则A中的初始空实例化不能在B中替换。另一个问题是引用类A需要初始化[或缺少(c)测试]中的缺省值。

帮助 - 建议 - 等赞赏。

A <- setRefClass('A', 
    fields = list(
     count = 'numeric' 
    ), 

    methods = list(
     initialize = function (c=0) { 
      cat('DEBUG: A$initialize(c); where c='); cat(c); cat('\n') 
      count <<- c 
     } 
    ) 
) 

instance.of.A <- A$new(10) 
str(instance.of.A) 

B <- setRefClass('B', 
    field = list(
     a = 'A', 
     b = 'A' 
    ), 

    methods = list(
     initialize = function(c) { 
      a <<- instance.of.A 
      b <<- getRefClass('A')$new(c) 
     } 
    ) 
) 

instance.of.b <- B$new(100) 
str(instance.of.b) 

回答

0

借鉴上面的,我使用的解决方案(有点长,因为类型检查的):

A <- setRefClass('A', 
    fields = list(
     count = function(x) { 
      if (!missing(x)) { 
       if(class(x) != 'numeric') 
        stop('Class A: count set by non-number') 
       .self$count.private <- x 
      } 
      .self$count.private 
     } 
    ), 

    methods = list(
     initialize = function (c=0) { 
      cat('DEBUG: A$initialize(c); where c='); cat(c); cat('\n') 
      count <<- c 
     } 
    ) 
) 

instance.of.A <- A$new(10) 
str(instance.of.A) 

B <- setRefClass('B', 
    field = list(
     a = function(x) { 
      if (!missing(x)) { 
       if(!inherits(x, 'envRefClass') || class(x)[1] != 'A') 
        stop('Class B: expecting instance of class A') 
       .self$a.private <- x 
      } 
      .self$a.private 
     }, 
     b = function(x) { 
      if (!missing(x)) { 
       if(!inherits(x, 'envRefClass') || class(x)[1] != 'A') 
        stop('Class B: expecting instance of class A') 
       .self$b.private <- x 
      } 
      .self$b.private 
     } 
    ), 

    methods = list(
     initialize = function(c) { 
      a <<- instance.of.A 
      b <<- getRefClass('A')$new(c) 
     } 
    ) 
) 

instance.of.b <- B$new(100) 
str(instance.of.b) 
2

这里有两个可能的解决方案:

  1. 不要设置字段属性:

    B <- setRefClass('B', 
        methods = list(
         initialize = function(c) { 
          .self$a = instance.of.A 
          .self$b =getRefClass('A')$new(c) 
         } 
        ) 
    ) 
    
  2. 组图场,但使用ANY类:

    B <- setRefClass('B', 
        field = (a="ANY", b="ANY"), 
        methods = list(
         initialize = function(c) { 
          a <<- instance.of.A 
          b <<- getRefClass('A')$new(c) 
         } 
        ) 
    ) 
    

这两种解决方案的缺点是该类型不是在ab执行,即

B$a = "Fred" 

现在是可能的。

+0

感谢 - 我猜想的答案,你的明显缺点是在外地使用类似sintax访问器方法,并在方法的设置部分包含类型检查。将测试并让你知道。 –