Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: how to define multiple constructors for an R6 class?

Tags:

r

r6

I am currently working on a project where I need to build an R6 class in R that can be initialized in more than one way. I am wondering what the best way is to go about it. 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 an R6 class MyClass with a field names that can be initialized using either using vector variable_names or a integer n_variables (in which case it initializes a default vector of names).

The functionality should work like this:

#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] "x y"

#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 took a look through the Introductory vignette, but there doesn't seem to be a clear way to do this.

Ideally, I am looking for a solution that does not force me to name the arguments (i.e. so I do not have to do something like myClass$new(names=variable_names)) and that lets me easily check that the inputs are valid.

like image 776
Berk U. Avatar asked Jan 26 '16 23:01

Berk U.


People also ask

How would you create a new R6 class?

Create a new R6 class object that on multipication of numbers. The class name and the result of class must be same always, as the R6Class() returns a R6 object that defines the class. We can then construct a new object from the class using the new() method which is accessed using the $ operator.

What is R6Class?

Description. R6 objects are essentially environments, structured in a way that makes them look like an object in a more typical object-oriented language than R. They support public and private members, as well as inheritance across different packages.

What is R6 R?

R6 is an implemention of encapsulated object-oriented programming for R, and is a simpler, faster, lighter-weight alternative to R's built-in reference classes. This style of programming is also sometimes referred to as classical object-oriented programming.


1 Answers

Possible way is to use dot-dot-dot (ellipsis) argument for constructor which allows you to pass arbitrary number of arguments into function. After that you have to convert the "..." to the list and parse input arguments.


For example suppose that 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)
      })
)

Calling the constructor 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
like image 73
Petr Javorik Avatar answered Oct 18 '22 13:10

Petr Javorik