[R] S4 vs Reference Classes

Joseph Park jpark.us at att.net
Wed Sep 14 15:01:14 CEST 2011

   Thanks Martin.
   What i'm hoping to do is have a class object, with a member method
   that can change values of slots in the object, without having to
   assign values by external assignment to the object. Something like this:
   setClass ( "Element",
     representation ( x  = "numeric", y  = "numeric" ),

     prototype = list( x = 0, y = 1 )
   setGeneric( name = "ComputeX",
               def  = function( self ) standardGeneric("ComputeX") )
   setMethod( "ComputeX", signature = "Element",
     function ( self ) {
       if ( self @ y > 0 ) {
         self @ x = pi
   so that a call to the method ComputeX assigns ('internally') a
   value to the slot x of the global object.
   One can do :
   a = new( 'Element' )
   a @ x = 2
   but i would prefer to have a class method do the work without
   having to explicitly call a @ x = 2. Having to do this means that
   i need code in my main processing app that does things on slots
   that normally i would do in a class method.
   As I understand it, Reference Classes provide this. So i'm
   naturally wondering if i should switch my app from S4 to RC.
   Fundamentally, I don't clearly understand S4 and what the difference
   is between creating a SetReplaceMethod vs a SetMethod, since it
   seems that in either case one has to 'externally' assign the slot
   value. My limitation, of course.
   On 9/14/2011 12:17 AM, Martin Morgan wrote:

     On 09/13/2011 10:54 AM, Joseph Park wrote:

         Hi, I'm looking for some guidance on whether to use
         S4 or Reference Classes for an analysis application
         I'm developing.
         I'm a C++/Python developer, and like to 'think' in OOD.
         I started my app with S4, thinking that was the best
         set of OO features in R. However, it appears that one
         needs Reference Classes to allow object methods to assign
         values (other than the .Object in the initialize method)
         to slots of the object.

       setClass("A", representation=representation(slt="numeric"))
     a slot can be updated with @<- and an object updated with a replacement
       setGeneric("slt<-", function(x, ..., value) standardGeneric("slt<-"))
       setReplaceMethod("slt", c("A", "numeric"), function(x, ..., value) {
           x at slt <- value
     > a = new("A", slt=1)
     > slt(a) = 2
     > a
     An object of class "A"
     Slot "slt":
     [1] 2
     The default initialize method also works as a copy constructor with
     validity check, e.g., allowing multiple slot updates
       setReplaceMethod("slt", c("A", "ANY"), function(x, ..., value) {
           initialize(x, slt=as.numeric(value))
     > slt(a) = "1"

         This is typically what I prefer: creating an object, then
         operating on the object (reference) calling object methods
         to access/modify slots.
         So I'm wondering what (dis)advantages there are in
         developing with S4 vs Reference Classes.

     R's copy-on-change semantics leads me to expect that
     b = a
     slt(a) = 2
     leaves b unchanged, which S4 does (necessarily copying and thus with a
     time and memory performance cost). A reference class might be appropriate
     when the entity referred to exists in a single copy, as e.g., an on-disk
     data base, or an external pointer to a C++ class.

         Things of interest:
         Performance (i.e. memory management)
         Integration compatibility with R packages
         ??? other issues
     [1]R-help at r-project.org mailing list
     PLEASE do read the posting guide
     and provide commented, minimal, self-contained, reproducible code.


   1. mailto:R-help at r-project.org
   2. https://stat.ethz.ch/mailman/listinfo/r-help
   3. http://www.R-project.org/posting-guide.html

More information about the R-help mailing list