R: how to define several constructors for class R6?

I am currently working on a project where I need to create an R6 class in R that can be initialized in more than one way. I am wondering how best to do this. Is it possible to overload the $new() function? Or do I need to define a helper function?

As a motivating example: I would like to have two constructors for the R6 class MyClass with the names field, which can be initialized using either the variable_names vector or the integer n_variables (in this case, it initializes the default name vector).

Functionality should work as follows:

 #define the class (only has a constructor that accepts a vector of names) myClass <- R6Class("myClass", public = list( names = NA, initialize = function(names) { if (!missing(names)) self$names <- names }) ) #create a test object using a vector of names variable_names = c("x","y") a = myClass$new(variable_names) a$names #> [1] "xy" #everything after here does not actually work (just to illustrate functionality) n_variables = 2; b = myClass$new(n_variables) b$names #> [1] "v1 v2" 

I looked through the introductory vignette , but there seems to be no clear way to do this.

Ideally, I am looking for a solution that does not force me to specify arguments (i.e. I do not need to do something like myClass$new(names=variable_names) ), and this allows me to easily verify that the inputs are valid.

+5
source share
1 answer

A possible way is to use the dot-dot-dot (ellipsis) argument for a constructor that allows you to pass an arbitrary number of arguments to a function. After that, you need to convert "..." to a list and parse the input arguments.


For example, suppose we want to overload the constructor by arity.

 myClass <- R6Class("myClass", public = list( name = NA, age = NA, favouriteFood = NA, # Constructor overloaded by arity initialize = function(...) { arguments <- list(...) switch(nargs(), # one input argument {self$name <- arguments[[1]]}, # two input arguments {self$name <- arguments[[1]] self$age <- arguments[[2]]}, # three input arguments {self$name <- arguments[[1]] self$age <- arguments[[2]] self$favouriteFood <- arguments[[3]]} ) print(self) }) ) 

The constructor call now gives us

 > a = myClass$new("john") <myClass> Public: age: NA clone: function (deep = FALSE) favouriteFood: NA initialize: function (...) name: john > a = myClass$new("john",35) <myClass> Public: age: 35 clone: function (deep = FALSE) favouriteFood: NA initialize: function (...) name: john > a = myClass$new("john",35,"pasta") <myClass> Public: age: 35 clone: function (deep = FALSE) favouriteFood: pasta initialize: function (...) name: john 
+4
source

Source: https://habr.com/ru/post/1241558/


All Articles