2016-01-22 26 views
1

如果您有活动绑定,似乎复制方法不起作用。R参考类别:具有活动绑定的复制方法

Example类:

test <- setRefClass("test", fields = list(x =function() y + 1 , y = "numeric")) 

初始化,它的工作原理确定:在副本

a <- test(y = 1) 
a$x 
[1] 2 
a$y 
[1] 1 

错误:

a$copy() 
Error in (function() : unused argument (quote(2)) 

这是预期的行为?

R.version 
platform  x86_64-w64-mingw32   
arch   x86_64      
os    mingw32      
system   x86_64, mingw32    
status          
major   3       
minor   1.2       
year   2014       
month   10       
day   31       
svn rev  66913      
language  R       
version.string R version 3.1.2 (2014-10-31) 
nickname  Pumpkin Helmet 
+0

活动绑定需要有形式'function(value){}'以允许赋值; 'copy()'试图将字段设置为旧的'值'。 –

+0

非常感谢@MartinMorgan!这种行为似乎仍然有点奇怪,因为没有参数的活动绑定很常见!根据您的回答,我创建了一种不尝试将值分配给活动绑定的复制方法,如有必要,请随时纠正我的答案! –

回答

0

根据马丁的评论,问题就出在默认copy方法的assign()部分:

for (field in names([email protected])) { 
     if (shallow) 
      assign(field, get(field, envir = selfEnv), envir = vEnv) 
     else { 
      current <- get(field, envir = selfEnv) 
      if (is(current, "envRefClass")) 
       current <- current$copy(FALSE) 
      assign(field, current, envir = vEnv) 
     } 
    } 

由于该领域是一个积极的不带任何参数结合,分配将失败。一个简单的解决方案似乎是为所有活动绑定提供参数。在我的情况下,我用了三个点。

test <- setRefClass("test", fields = list(x = function(...) y + 1 , y = "numeric")) 

现在复制方法正常工作。但是,如果您尝试将值分配给活动绑定(有时这是我在用例中所需的东西),该函数不会引发错误。

所以另一种解决办法我试过了重新定义复制方法做for循环只对那些不活跃的绑定字段:

test <- setRefClass("test", fields = list(x = function() y + 1, y = "numeric")) 

test$methods(copy = function (shallow = FALSE) 
{ 
    def <- .refClassDef 
    value <- new(def) 
    vEnv <- as.environment(value) 
    selfEnv <- as.environment(.self) 
    fields <- names([email protected])[[email protected]dClasses!= "activeBindingFunction"] 
    for (field in fields) { 
    if (shallow) 
     assign(field, get(field, envir = selfEnv), envir = vEnv) 
    else { 
     current <- get(field, envir = selfEnv) 
     if (is(current, "envRefClass")) 
     current <- current$copy(FALSE) 
     assign(field, current, envir = vEnv) 
    } 
    } 
    value 
} 
) 

好像在我测试的情况下工作正常。尽管我还没有完全测试过,所以我不知道它是否会在其他情况下崩溃。