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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With