Search code examples
rinheritancereference-class

Reference Class inheriting methods


I am re-factoring a package to use reference classes and running into an issue with the inheritance of methods.

I have a class, B, that contains (inherits) A. However, I cannot call any of the methods for an instance of class 'B' that are inherited. In fact, they don't even exist in the object.

How do I define a reference class that inherits methods from another class? Does it matter that the inherited methods are generic?

This is a self contained example to demonstrate the issue:

A <- setRefClass("A", fields=c("f1", "f2"))

B <- setRefClass("B", fields=c("f3"), contains="A")

setGeneric("f", function(.self) standardGeneric("f"))

setMethod(f,
  signature = c(.self="A"),
  definition = function(.self) {
    print("Hello from class A")
  }
)

setMethod(f, signature = c(.self="B"),
  definition = function(.self) {
    print("Hello from class B")
  }
)

A$methods(f=f)

a <- A$new()
b <- B$new()

Invoking the methods:

> a$f()
[1] "Hello from class A"

> b$f()
Error in envRefInferField(x, what, getClass(class(x)), selfEnv) : 
  ‘f’ is not a valid field or method name for reference class “B”

# Should print "Hello from class B"

Solution

  • I think it is just the matter of order: A$methods(f=f) is executed after the definition of class B. Simple modification of execution order helps:

    A <- setRefClass("A", fields=c("f1", "f2"))
    setGeneric("f", function(.self) standardGeneric("f"))
    setMethod(f,
              signature = c(.self="A"),
              definition = function(.self) {
                print("Hello from class A")
              }
    )
    
    A$methods(f=f)
    
    B <- setRefClass("B", fields=c("f3"), contains="A")
    setMethod(f, signature = c(.self="B"),
              definition = function(.self) {
                print("Hello from class B")
              }
    )
    
    a <- A$new()
    b <- B$new()
    
    a$f()
    #[1] "Hello from class A"
    b$f()
    #[1] "Hello from class B"