Reference Classes


Defines and uses reference class objects.


setRefClass(Class, fields = character(), contains = character(),
            methods = list(), where = topenv(parent.frame()), ...)
getRefClass(Class, where = topenv(parent.frame()))
initRefFields(.Object, classDef, selfEnv, args)


Class a character string name of a reference class to define. In getRefClass, this argument can also be a refClassRepresentation object defining a reference clas.
fields a list or a string vector specifying the field names and classes for this new reference class.
  • If this argument is a list, the list element names give the names of the fields, and the list values specify the class for each field.
    • If a list value is a string, it gives the class allowed for this field, or "ANY" to specify any object is permitted.
    • If the list value is a function, it is installed as an active binding for reading/writing the field value with makeActiveBinding.
  • If the fields argument is a string vector, the string values give the field names of fields with class "ANY". These field specifications override any inherited fields with the same name defined in superclasses.
contains A string vector of class names for the superclasses of this new class. An error is generated if any of these are not defined classes. Any classes in this vector that are not reference classes are ignored.
methods A list giving methods associated with this reference class. Each list element name gives the name of a method, and the corresponding list element is the function definition for the method.
where this argument is unimplemented.
... this argument is unimplemented.
.Object A reference object to be initialized.
classDef A refClassRepresentation object specifying the reference class of .Object.
selfEnv The environment object used to store the fields and methods for .Object.
args A list of arguments giving the field names and field values for initializing .Object.


The Reference Class system is an object system built on top of the S4 object system. Whereas S4 classes are defined with setClass, reference classes are defined with setRefClass. Like the S4 class system, reference classes are defined inheriting from one or more other reference classes, and classes specify object fields with associated field classes.
One big difference between S4 classes and reference classes is that an instance of a reference class is represented by an environment object containing the object fields and methods. Because of this, the field values of a reference object can be changed without copying the object, and it is possible to have aliasing between different pointers to a reference object, in contrast to the normal copy-on-write semantics of S4 objects.
This implementation of reference classes results in a subtle change in function semantics: reference class methods need to be able to access the fields defined within the object, as well as other variables such as .self to reference the object itself, and .refClassDef to reference the object's reference class. This is done by adding the methods to the objects environment object, while changing the parent environment of the method function to point to this object. Because the function's environment is changed, this means that the normal lexical scoping rules do not apply, and a reference class method cannot access the variables defined at the point when it was defined. The environment of a function passed to the fields argument is changed the same way, so that the active binding for the field can access the fields in the reference object.
The fields and methods of a reference object are normally accessed using the "$" operator. In addition to accessing an object's named field or method, this also will copy a superclass method from a superclass to the object's envonment object, if it has not already beed copied. Thus, the methods are not copied until they are used. A number of such methods defined for the superclass of all reference classes, envRefClass, described below.
setRefClass and getRefClassreturn a refObjectGenerator object that can be used to create an object of the specified reference class.
initRefFieldsreturns the initialized .Object value.
See Also
setClass, makeActiveBinding
# Create a new reference class, and an instance of it
gen <- setRefClass("myRefClass", fields=list(aa="integer", bb="ANY"))
x <- gen$new(aa=123L, bb=3.4)
# Extract and set a field
x$aa <- 456L
## Not run: 
# Generate an error on trying to set the field to a non-integer
try(x$aa <- "notAnInteger")
## End(Not run)
# Can put any value in a field of type "ANY"
x$bb <- "foo"

# One way to create a new object: # Call the "new" method on a refObjectGenerator object xClass <- getRefClass("myRefClass") x <- xClass$new(aa=123L, bb=3.4)

# A second way to create a new object: # Use the refObjectGenerator as a function xClass <- getRefClass("myRefClass") x <- xClass(aa=123L, bb=3.4)

# A third way to create a new object: # Call the "new" function with the class name x <- new("myRefClass", aa=123L, bb=3.4)

# Make reference class inheriting from the above class gen2 <- setRefClass("myRefClass2", contains="myRefClass", fields=list(cc="character")) # Create instance specifying fields (including inherited ones) x2 <- gen2$new(aa=1L, bb=2.3, cc="foo")

# Define reference class with a method gen3 <- setRefClass("myRefClass3", fields=list(dd="numeric"), methods=list(getval=function() dd, setval=function(value) dd <<- value)) x3 <- gen3$new(dd=1.2) # Call methods to extract/set value of "dd" field x3$getval() # returns 1.2 x3$setval(3.4) x3$getval() # now returns 3.4 ## Not run: # Gives error if you try to set field to incorrect class try(x3$setval("foo")) ## End(Not run)

# Define subclass of the above class with a method calling callSuper gen4 <- setRefClass("myRefClass4", contains="myRefClass3", methods=list(getval=function() 2*callSuper())) x4 <- gen4$new(dd=100) x4$getval() # returns 200

# Define method with an "initialize" method modifying field values # field "x" is set to twice the specified value, defaulting to 100 # field "y" is set to "none" if not specified explicitly gen5 <- setRefClass("myRefClass5", fields=list(x="numeric",y="character"), methods=list(initialize=function(..., x=100L) {x <<- 2*x; y <<- "none"; callSuper(...)})) gen5$new() # initializes field "x" to 200, "y" to "none" gen5$new(x=10) # initializes field "x" to 20, "y" to "none" gen5$new(y="abc") # initializes field "x" to 200, "y" to "abc"

# Define a field as a function used for an active binding gen6 <- setRefClass("myRefClass6", methods=list(initialize=function(...) {saveVal <<- 0; numSet <<- 0; callSuper(...)}), fields=list(saveVal="numeric", numSet="numeric", value=function(value) { if(missing(value)) { saveVal } else { numSet <<- numSet+1 saveVal <<- value value }})) x6 <- gen6$new() x6$value # returns 0 x6$numSet # returns 0 x6$value <- 123 x6$value # returns 123 x6$numSet # returns 1 x6$value <- 456 x6$value # returns 456 x6$numSet # returns 2

Package methods version 4.0.0-28
Package Index