Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R, R6 Operator Overloading

Consider the following:

A = R6::R6Class("ClassA")
B = R6::R6Class("ClassB")

`+.ClassA` = function(o1,o2) o1 #Trivial Example, Usually do something
`+.ClassB` = function(o1,o2) o1 #Trivial Example, Usually do something

a = A$new()
b = B$new()

a + b

Which throws an error:

Warning: Incompatible methods ("+.ClassA", "+.ClassB") for "+"
Error in a + b : non-numeric argument to binary operator

How can the above be resolved, so both A and B can overload the + operator, and be added together.

like image 408
Nicholas Hamilton Avatar asked May 26 '16 13:05

Nicholas Hamilton


People also ask

What is R6 class?

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. Some features of R6: R6 objects have reference semantics.

What does the public argument to the R6Class () function do?

The public argument is a list of items, which can be functions and fields (non-functions). Functions will be used as methods. The $new() method creates the object and calls the initialize() method, if it exists. Inside methods of the class, self refers to the object.

Can you overload an operator twice?

No this is not possible. The compiler can't know which version you want, it deducts it from the parameters. You can overload many times, but not by the return type.

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.


1 Answers

Thought I would post my answer, I assign the class 'IAddable' to both R6 prototypes (sort of like interface declaration in other languages)

A = R6::R6Class(c("ClassA","IAddable"))
B = R6::R6Class(c("ClassB","IAddable"))

Then we can assign a single overloaded operator, which will be called by all objects that inherit from this interface class declaration.

`+.IAddable` = function(o1,o2) o1 #Trivial Example, Usually do something

This then works as expected:

a = A$new()
b = B$new()

a + b  #WORKS, RETURNS a
b + a  #WORKS, RETURNS b
like image 102
Nicholas Hamilton Avatar answered Oct 22 '22 03:10

Nicholas Hamilton