1

I'm relatively new at OOP and need advice: What is the best way to overload the Arithmetic generic operators in reference classes in R?

For example, suppose I define

bar <- setRefClass( "foo", fields=list(a="numeric", b="numeric" ))

If I try the obvious thing:

> bar$new(a=3,b=1) + bar$new(a=1,b=3)  
Error in bar$new(a = 3, b = 1) + bar$new(a = 1, b = 3) :  
non-numeric argument to binary operator

What is the recommended way to do something like (a+a) + (b+b)?

  • I can't for the life of me figure out what you wanted to do, but look: `rab <- bar$new(a=3,b=1) ; class(rab) ; rab$a ` will point out a couple problems. You'll need to define a `+` method which tears apart your objects and puts them back together. Unless you have a strict need to interact with an OOP language, I'd recommend avoiding `RefClass`es and using the standard `R` classes and methods. – Carl Witthoft Aug 09 '13 at 17:02
  • I am working with massive datasets, so using standard R with its pseudo copy-by-value methods causes memory headaches. Reference classes are extremely helpful for this problem, and I find them extremely helpful. When combined with data.table, I can replicate many of the facilities in sqldf and ff with very little effort. – Andrew Zachary Aug 10 '13 at 16:34

1 Answers1

3

You can take advantage of the fact that reference classes are S4 + environments, and define an S4 method:

bar <- setRefClass("foo", fields = list(a = "numeric", b = "numeric"))
one <- bar$new(a = 1, b = 1)
two <- bar$new(a = 2, b = 2)

# Find the formals for + with getGeneric("+")
setMethod("+", c("foo", "foo"), function(e1, e2) {
  bar$new(a = e1$a + e2$a, b = e1$b + e2$b)
})
one + two

It's similarly easy to define a set of methods for a group generic:

setMethod("Ops", c("foo", "foo"), function(e1, e2) {
  bar$new(a = callGeneric(e1$a, e2$a), b = callGeneric(e1$b, e2$b))
})
one / two
hadley
  • 102,019
  • 32
  • 183
  • 245