Working with the reference class

There is also a class system that has reference semantics. It is more like the class system in other object-oriented programming languages.

First, to define a reference class (RC), we supply a class definition to setRefClass(). Unlike the S4 class system where we use new() to create an instance, setRefClass() returns an instance generator. For example, we define a class named Vehicle, which has two fields: a numeric position and a numeric distance. We store the instance generator to a variable named Vehicle:

Vehicle <- setRefClass("Vehicle",  
  fields = list(position = "numeric", distance = "numeric")) 

To create an instance, we use Vehicle$new to create new instances of the Vehicle class:

car <- Vehicle$new(position = 0, distance = 0) 

Unlike S4, the fields of RC are not slots, so we can use $ to access them:

car$position 
## [1] 0 

Each instance we create with Vehicle$new is an object of reference semantics. It behaves like a combination of S4 object and environment.

In the following code, we will create a function that modifies the fields in a Vehicle object. More specifically, we define move that modifies position in relative terms, and all movements are accumulated to distance:

move <- function(vehicle, movement) { 
  vehicle$position <- vehicle$position + movement 
  vehicle$distance <- vehicle$distance + abs(movement) 
} 

Now, we will call move with car, and the instance we created is modified rather than copied:

move(car, 10) 
car 
## Reference class object of class "Vehicle" 
## Field "position": 
## [1] 10 
## Field "distance": 
## [1] 10 

Since RC itself is a class system more like ordinary object-oriented system, a better way to do this is to define its own methods of the class:

Vehicle <- setRefClass("Vehicle",  
  fields = list(position = "numeric", distance = "numeric"), 
  methods = list(move = function(x) { 
    stopifnot(is.numeric(x)) 
    position <<- position + x 
    distance <<- distance + abs(x) 
  })) 

Unlike S3 and S4 systems where methods are stored in the environment, RC directly include its methods. Therefore, we can directly call the method inside an instance. Note that to modify the value of a field in a method, we need to use <<- instead of <-. The following code is a simple test to check whether the method works and whether the reference object is modified:

bus <- Vehicle(position = 0, distance = 0) 
bus$move(5) 
bus 
## Reference class object of class "Vehicle" 
## Field "position": 
## [1] 5 
## Field "distance": 
## [1] 5 

From the preceding examples, we can see that RC looks more like the objects in C++ and Java. For more detailed introduction, read ?ReferenceClasses.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset