Search code examples
rmethodsr6generic-function

how to dispatch summary() method in R6 object


I am using R6 to build an object which fields includes a data frame and other informations.
I defined a first method $print() which I can call as obj1$print() or print(obj1) and both ways works just fine.

> obj1$print()
test object name: AA
> print(obj1)
test object name: AA

I defined a second method $summary(), which is a generic function same as $print(): in this case the call obj1$summary() works as expected:

> obj1$summary()
test object name: AA
     alpha               beta  
 Min.   :-1.63751   a      :1  
 1st Qu.:-0.38065   b      :1  
 Median :-0.05854   c      :1  
 Mean   :-0.01360   d      :1  
 3rd Qu.: 0.46194   e      :1  
 Max.   : 1.34755   f      :1  
                    (Other):4 

but summary(obj1) returns an error:

Error in object[[i]] : wrong arguments for subsetting an environment

The example code is as follows:

testobj <- R6::R6Class(classname = "testobj",
                       public = list(
                         name = NULL,
                         data = NULL,
                         initialize = function(name, data) {
                           self$name <- name
                           self$data <- data
                         },
                         print = function(...) {
                           cat("test object name: ", self$name, "\n", sep = "")
                           invisible(self)
                         },
                         summary = function() {
                           cat("test object name: ", self$name, "\n", sep = "")
                           summary(self$data)
                           }
                         )
                       )

obj1 <- testobj$new(name = "AA",
                   data = data.frame(alpha = rnorm(10),
                                     beta = letters[1:10]))

My understanding is that within an object you can define methods with the same name as generic functions and those methods are dispatched automatically to the function based on the class of the object, as it happens to $print(). Isn't that correct?
Why the same approach does not works with $summary()? How can I fix that?

Many thanks for the help.


Solution

  • S3 methods, which is what you're looking for are different than R6 methods. For one thing, they aren't part of the object.

    Make an S3 method for your class:

    summary.testobj <- function(obj) {
        obj$summary()
    }
    
    summary(obj1)