Reputation: 2056
Is the function initFields not a good way to initialize arbitrary fields of a reference class? If not what would you suggest? And how could I handle the a field of type "ANY", because for the string "ANY" I cant do a call like do.call(fields[[i]],list())
Part.initFields<-function(args){
argNames <- names(args)
fields<-.self$getRefClass()$fields()
fieldNames <- names(fields)
for(i in seq_along(fields)){
var <- if(is.null(args[[fieldNames[i]]])) do.call(fields[[i]],list())
else do.call(paste("as.",fields[[i]],sep=""),list(args[[fieldNames[i]]]))
assign(fieldNames[[i]], var, attr(.self, ".xData"))
}
}
Part.initialize<-function(...){
args<-list(...)
.self$initFields(args)
.self
}
Part<-setRefClass(Class = "Part"
,fields = c(var1 = "numeric", var2 = "character")
,methods = list(initialize=Part.initialize
,initFields=Part.initFields))
part<-Part$new(var1=1)
Upvotes: 1
Views: 99
Reputation: 46856
Use the initialize method to coerce arguments. Explicitly exclude
coercions that you do no wish to perform. Coerce using as(x, "class")
instead of trying to construct function names from character strings. Do not re-implement
initFields
.
Part <- setRefClass(Class = "Part",
fields=c(var0 = "ANY", var1 = "numeric", var2 = "character"),
methods=list(
initialize=function(...) {
args <- list(...)
map <- .self$getRefClass()$fields(); map <- map[map != "ANY"]
idx <- names(args) %in% names(map)
args[idx] <- Map(as, args[idx], map[names(args)[idx]])
do.call(.self$initFields, args)
}))
Simple test cases
Part()
Part(var2=1:3)
Upvotes: 2