Question

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)
Was it helpful?

Solution

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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top