Skip to content
Prev 303332 / 398506 Next

pass by reference

Hi,
On Aug 14, 2012, at 10:07 AM, Bert Gunter wrote:

            
Almost off list!
I wonder why Reference Classes are not mentioned - I think they maybe be informally called R5 and RefClass, too.    You can learn about them with ?setRefClass.

I have tried using this approach quite recently as I was working with very large data frames.  I'm no software engineer, so I am not sure if using R5 style was a significant help to my problem, but with one exception it was pretty painless to give it a shake.*   In fact, inside the methods (and therefore the object instance environment?) I probably was working in the pass-by-value paradigm. 

I'm hoping that those in the know could shed some light on the pros and cons of using Reference Classes.

Cheers,
Ben

* There are two ways to add methods to a reference class: (1) in the call to setRefClass() which generates the object definition, and (2) using the MyRefClass$methods() function after the generator object is created. After some puzzle-filled afternoons I settled on the latter as being waaaaay better. I have pasted below an example.

##### START

# generator
MyRefClassR5 <- setRefClass("MyRefClassR5",

   # here are the field properties
   fields = list(
      x = "numeric",
      y = "numeric",
      color = "character",
      flavor = "character"),
      
   # here we can add methods - but there is a handier way 
   # see the length() method added below
   methods = list(
      plot = function(color = .self$color, flavor = .self$flavor, pch = 15, ...){
         graphics::plot(.self$x, .self$y, col = color, main = flavor, pch = pch, ...)
         speak("plotting")
      },
      
      speak = function(message = paste(.self$flavor, "is the color", .self$color)){
         cat("MyRefClass:", message, "\n")
      })
  )    
  
  MyRefClass <- function(x = seq(from = 0, to = 10), y = x^2,
   color = "brown", flavor = "chocolate"){
      
      X <- MyRefClassR5$new(x = x, y = y,
         color = color, flavor = flavor)
         
      return(X)
 }
 
# create an instance, a
a <- MyRefClass()
a$speak()
a$plot()
 
# So, now I have an instance, a, of MyRefClassR5.  
# But suppose I want to add a new method called length.
# this is a handier way to add methods as it adds them to existing 
# instances of the class - if this new method is added above in the 
# setRefClass() generator, then subsequent instances of the object would
# have a length() method, but object a would be orphaned without it.
 MyRefClassR5$methods(
   length = function(){
      len <- c(x = base::length(.self$x), y = base::length(.self$y))
      s <- paste("length x =", len["x"], " length y =", len["y"])
      speak(s)
      return(len)
   })
   
# can I use this method on instance a?  Yup!
a$length()


#### END
Ben Tupper
Bigelow Laboratory for Ocean Sciences
180 McKown Point Rd. P.O. Box 475
West Boothbay Harbor, Maine   04575-0475 
http://www.bigelow.org