R Programming: Use of setMethod to override the 'summary' function for a group of classes

StackOverflow https://stackoverflow.com/questions/17124463

  •  31-05-2022
  •  | 
  •  

Question

I am using setMethod to override the 'summary' function for objects of different classes.

Originally, I used this approach:

setMethod('summary', "class_1",
           function(object, ...) {
            #code for class_1 summary here...
          }          
)

setMethod('summary', "class_2",
          function(object, ...) {
            #code for class_2 summary here...
          }          
)

setMethod('summary', "class_3",
          function(object, ...) {
            #code for class_3 summary here...
          }          
)

...and so on for each class.

However, there are 12 different classes altogether, so the code became very repetitive. Wishing to avoid such repetition, I created a function containing the class names:

all_classes = function() {
  c("class_1", "class_2", "class_3") #and so on for each class
}

Then I used lapply:

lapply(
  1:length(all_classes()),
  function(k)
    setMethod('summary', all_classes()[k],
                function(object, ...) {
                  #code here...
                }
    )
)

This works, but I would like to know if there is a better way of achieving my aim of compactly creating a 'summary' function for each different class.

Thanks,

John.

Was it helpful?

Solution

A facade pattern implements light-weight methods on top of an underling work-horse function. Usually each method does some preliminary processing before invoking the work-horse function. In the simple case where there is no preliminary processing and you have no interest in the return value of setClass, it makes sense to use a for loop rather than lapply. So

.my_summary <- function(object, ...) {}
for (cl in all_classes())
    setMethod(summary, cl, .my_summary)

Also, that .my_summary works on several classes implies that the classes share common structure, hence might be arranged into a class hierarchy and a method defined on the base class.

setClass("A", representation(x="numeric"))
setClass("A1", contains="A")
setClass("A2", contains="A")
setMethod(summary, "A", function(object, ...) {})

In S4 one can use multiple inheritance to provide a kind of aspect-oriented programming

setClass("Summary")
setMethod(summary, "Summary", function(object, ...) {})
setClass("B1", contains=c("A", "Summary"))

B1 then inherits data (slot x) from A, and behavior from Summary. Method dispatch in this case can get confusing (which method is selected if both A and Summary have a summary method?).

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