setRefClass
Reference Classes

### Description

Defines and uses reference class objects.

### Usage

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

### Arguments

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.

### Details

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.

- Creating and Initializing Reference Objects

  setRefClass and getRefClass | These functions return an object with class refObjectGenerator that can be used to create new objects of the specified reference class by using the new method, specifying the initial values for zero or more of the fields. A refObjectGenerator object is also a function, which can be called directly to create a new object of the reference class. The new function can also be used to create reference objects for the reference class. The fields in a newly-created reference object are initialized by calling the reference class method initialize, passing the arguments given to the new method or function. This method is not defined by default; if it is not found, the object is initialized by calling the function initRefFields, passing the arguments given to the new method or function as its args argument. initRefFields extracts the elements of the args argument, and assigns the object fields appropriately. It is possible to modify the initialization process by defining an initialize method. This can call callSuper to call any inherited initialize method defined in a superclass. If no inherited initialize method is defined, this will call the initFields method, which can also be redefined in a reference class.

- Variables Accessable by Reference Object Methods

  When a reference object is created, several variables are defined in its environment object. These can be accessed by any of the reference class methods:

  .self | This variable contains the reference object itself.
  .refClassDef | This variable contains a refClassRepresentation class definition object, as would be returned by the getClass method.

- Reference Class Methods for class envRefClass

  All reference objects inherit the following methods from the reference class envRefClass:

  callSuper(...) | A special method that, when called from within another method, calls the inherited method with the same name. If this is not called from within a reference class method, it generates an error.
  copy(shallow=FALSE) | Creates a copy of the reference object with a new environment object pointing to the fields. If shallow is FALSE, this same copying is done recursively for reference objects contained as values of the object fields. If shallow is TRUE, none of the top-level object field values are copied.
  export(Class) | If Class is a subclass of the object's class, this method returns the object. Otherwise, this method coerces the object to the specified class.
  field(name, value) | Used to get or assign programmatically the field whose name is name. If the value argument is missing, this returns the value of the specified field. If the value argument is not missing, this method sets the field to the specified value.
  getClass(...) | Returns the class definition of the object as a refClassRepresentation object.
  getRefClass(Class=.refClassDef) | Calls the function getRefClass to return a refObjectGenerator object for the specified class. If the Class argument is not given, this method returns a refObjectGenerator for the object reference class.
  import(value, Class=class(value)) | Sets the fields of this object from a superclass object. First, it tries to convert value to the class Class, using export method if it is a reference object, or the as function otherwise. Then, if Class is a superclass of this reference object, it extracts each of value fields and assigns it into this object. If Class is not a superclass, it generates an error.
  initFields(...) | This method initializes the fields of the object from the ... arguments, which can be named arguments to specify the value of named fields, or unnamed arguments to include a reference object, all of whose fields are used.
  show() | Prints the object. It is called by the show function, so it can be redefined to modify the printed representation of a reference object.
  trace(..., classMethod=FALSE) | Currently just prints a warning that it is not implemented.
  untrace(..., classMethod=FALSE) | Currently just prints a warning that it is not implemented.
  usingMethods(...) | Called in a method definition to indicate that the calling method needs to call the method names specified in its arguments (as unevaluated name or string arguments). When setRefClass defines a reference class with methods, each method function is analyzed to determine which other methods it calls, so that these other methods can be copied to the reference object, and they will be accessable from the method code. However, this works only for methods called directly in the code. If another method is called via do.call or eval, the code analyzer might not detect it. Thus, one can include calls to usingMethods to provide this information directly to the code analyzer. When usingMethods is actually executed, it does nothing but just returns NULL.

- Reference Class Methods for class refObjectGenerator

  The setRefClass and getRefClass functions return a reference object with class refObjectGenerator, which can be used to create new objects of the specified reference class by calling the new method. The following methods are available for refObjectGenerator objects:

  accessors(...) | Constructs and adds methods to the reference class for accessing specified fields. It takes one or more string vectors naming fields in the reference class, and then creates pairs of methods for reading and writing each of these fields. For example, if one of the fields is named "abc", it adds a method getAbc() for reading the field, and a method setAbc(value) for setting the field.
  fields() | Returns a named string vector, where the names are the field names for the reference class, and the string vector values are the classes of the fields. If a field has been specified as a function, this returns the class "activeBindingFunction" for that field.
  help(topic) | Currently just prints a warning that it is not implemented.
  lock(...) | Currently not implemented. Generates an error.
  methods(...) | If called with no arguments, it returns a string vector giving all the methods available in this reference class, either defined directly in this class, or inherited from superclasses. If this is called with one or more arguments, the arguments specify methods that should be added to the reference class. In this case, it can either have one argument, a list of named functions, or multiple named arguments, each of which should be a function. The names are used for method names, and the functions are added as the definitions of these methods.
  new(...) | Creates a new reference object from this reference class using the arguments to specify field values for the new object.

Value

setRefClass and getRefClass | return a refObjectGenerator object that can be used to create an object of the specified reference class.
initRefFields | returns the initialized .Object value.

See Also
setClass, makeActiveBinding
Examples

    # 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
    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 6.1.5-18
Package Index