2016-01-22 1 views
1

Кажется, что метод копирования не работает, если у вас есть активное связывание.R Reference Class: метод копирования с активными привязками

Пример Класс:

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

Initializing, он работает нормально:

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

Основываясь на комментарии Мартина, проблема лежит на assign() частях методы по умолчанию copy:

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")) 

Теперь метод копирования работает нормально. Но функция не выдает ошибку, если вы пытаетесь присвоить значения активным привязкам (иногда это то, что мне нужно в случаях использования, которые у меня есть).

Так другое решение, которое я попытался было переопределить метод копирования делает цикл только для тех полей, которые не являются активными привязок:

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]!= "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 
} 
) 

Это, кажется, работает нормально, в тех случаях, я испытал. Я не тестировал это полностью, поэтому, я не знаю, будет ли он ломаться в других случаях.

Смежные вопросы