R - How to overload the `$` operator in a Reference Class?

Tag: r , oop , operator-overloading , reference-class Author: zizizhuzhu Date: 2014-01-01

I'm having trouble overloading the $ operator and using callNextMethod() in a Reference Class. For instance, why does the following:

ClassA <- setRefClass("ClassA", fields = list(z = "numeric"))
setMethod("$",
    signature(x = "ClassA"),
    function(x, name) {
        value <- callNextMethod(x, name)   # Use the usual '$' operator to get field
        value^2
    }
)

myObj <- ClassA(z = 2)
myObj$a

produce an error?

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

I was expecting:

[1] 4

From what I can make out from the error message, somewhere down the line R starts looking for a field in myObj named "name" instead of "a". Strange...

Edit

After much debugging, I found that the cause was in fact in the 'next method' itself, which turns out to be methods:::.dollarForEnvRefClass. For some reason, it uses substitute() on name first:

methods:::.dollarForEnvRefClass
function (x, name)  {
    what <- substitute(name)        # WHY DO THIS????
    if (is.symbol(what)) 
        what <- as.character(what)
    else what <- name
    # ETC...
}

Why do this?? R calls my overloaded $operator the name as a character - I would expect to dispatch to the 'next method' with name remaining as a character...