Question

I need to use eval to call a reference class method. Below is a toy example:

MyClass <- setRefClass("MyClass",

    fields = c("my_field"),

    methods = list(

        initialize = function(){
            my_field <<- 3
        },

        hello = function(){
            "hello"
        },

        run = function(user_defined_text){
            eval(parse(text = user_defined_text))
        }
    )
)

p <- MyClass$new()
p$run("hello()") # Error: could not find function "hello" - doesn't work
p$run(".self$hello()") # "hello" - it works
p$run("hello()") # "hello" - now it works?!

p <- MyClass$new()
p$run("my_field") # 3 - no need to add .self

I guess I could do eval(parse(text = paste0(".self$", user_defined_text))), but I don't really understand:

  • why is .self needed to eval methods, but not fields?
  • why is .self no longer needed after it has been used once?
Was it helpful?

Solution

'Why' questions are always challenging to answer; usually the answer is 'because'. On ?setRefClass we eventually have

Only methods actually used will be included in the environment
corresponding to an individual object.  To declare that a method
requires a particular other method, the first method should
include a call to '$usingMethods()' with the name of the other
method as an argument. Declaring the methods this way is essential
if the other method is used indirectly (e.g., via 'sapply()' or
'do.call()'). If it is called directly, code analysis will find
it. Declaring the method is harmless in any case, however, and may
aid readability of the source code.

I'm not sure this is entirely helpful in your case, where the user is apparently able to specify any method. Offering a little unasked editorial comment, I'm not sure 'why' you'd want to write a method that would parse input text to methods; I've never used that paradigm myself.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top