stevec
stevec

Reputation: 52238

How to define a new class method in R?

Defining a new function is straight forward - e.g. myfunct <- function(x) { x * 2}

How can we define a new class method in R, such that obj$newmethod calls method newmethod on the object obj?

Desired output

How can we define a method on obj so that it can be called like so

obj <- 3
obj$newmethod
[1] 6

What I tried so far

newmethod <- function(x) { 
  x * 2
}

obj$newmethod

# Error in obj$newmethod : $ operator is invalid for atomic vectors

Examples of existing class methods

RSelenium package uses a lot of class methods, for example remDr$closeServer() calls the method closeServer() on the object remDr (which is of class remoteDriver) - there are many more examples under the Fields section of the manual (pages 9 - 13).

Upvotes: 1

Views: 833

Answers (2)

G. Grothendieck
G. Grothendieck

Reputation: 269471

1) Reference Classes RSelenium uses Reference Classes which is an OO system that is included with R. Rselenium defines 3 reference classes: errorHandler, remoteDriver and webElement.

In terms of the example in the question we can use the code below. No packages are used in the code here.

For more information on reference classes see ?ReferenceClasses.

# define class, properties/fields and methods
Obj <- setRefClass("Obj", 
  fields = list(obj = "numeric"),
  methods = list(
    newmethod = function() 2 * obj
  )
)

# instantiate an object of class Obj
obj1 <- Obj$new(obj = 3)

# run newmethod
obj1$newmethod()
## [1] 6

2) proto The example code in the question suggests that you may be looking for an object based (rather than class based) system. In that case the proto package provides one and your example works with a slight change in syntax.

library(proto)

p <- proto(obj = 0, newmethod = function(.) 2 * .$obj)
p$obj <- 3
p$newmethod()
## [1] 6

3) local If you don't need inheritance and other features of object orientation you could just do this. No packages are used.

Obj <- local({
  obj <- 0
  newmethod <- function() 2 * obj
  environment()
})

Obj$obj <- 3
Obj$newmethod()
## [1] 6

4) S3 S3 is included with R and is the most widely used OO system in R; however, it is different than conventional OO systems being based on the ideas of the dylan language so it may not correspond exactly to what you are looking for.

# constructor 
obj <- function(x) structure(x, class = "obj")

# method
newmethod <- function(x, ...) UseMethod("newmethod")
newmethod.obj <- function(x, ...) 2 * x

# create object obj3 of class "obj" and apply newmethod to it.
obj3 <- obj(3)
newmethod(obj3)
## [1] 6

5) Other Other OO systems are S4 (included in R), the R6 package and the R.oo package. Also try demo("scoping") for another approach.

Upvotes: 2

d.b
d.b

Reputation: 32548

For simple cases, you could do

f = function(x, newmethod = 2 * x) {
    list(x = x, newmethod = newmethod)
}

obj = f(3)

obj$newmethod

Upvotes: 1

Related Questions