It seems that the copy method does not work if you have an active binding.
Example class:
test <- setRefClass("test", fields = list(x =function() y + 1 , y = "numeric"))
Initializing, it works ok:
a <- test(y = 1)
a$x
[1] 2
a$y
[1] 1
Error on copy:
a$copy()
Error in (function () : unused argument (quote(2))
Is this the expected behavior?
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
Based on Martin's comment, the problem lies on the assign()
part of the default copy
method:
for (field in names(def@fieldClasses)) {
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)
}
}
Since the field is an active binding with no arguments, the assignment will fail. One easy solution seems to be providing arguments to all active bindings. In my case I used the three dots.
test <- setRefClass("test", fields = list(x = function(...) y + 1 , y = "numeric"))
Now the copy method works fine. But the function does not throw an error if you try to assign values to active bindings (sometimes that is something I need in the use cases I have).
So another solution I tried was to redefine the copy method doing the for loop only for those fields that are not active bindings:
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(def@fieldClasses)[def@fieldClasses!= "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
}
)
It seems to work ok in the cases I have tested. I have not tested this thoroughly though, so I don't know if it would break in other cases.