Reputation: 642
If I have an S3 class that inherits from a parent, how can I return a list of generic methods that I can call - both from the S3 class and the parent.
So the class of the created objects is:
c("my_s3_class", "parent_s3_class")
The following works fine for returning the methods on my_s3_class
:
methods(class = my_s3_class)
But it doesn't include generic functions that are callable, but only implemented in the parent, parent_s3_class
.
Ultimately I want to call every method using something like the below (this works, but doesn't include parent generic methods). The use of get()
means that I can't use NextMethod()
which otherwise would have been a reasonable workaround. Note I have an instance of my_s3_class
which I've represented as my_s3_class_instance
- this is just an implementation detail tho.
result <- sapply(methods(class = class(my_s3_class_instance)[1]),
function(f) {
print(paste("Executing:",f))
get(f)(my_s3_class_instance)})
Any ideas? Thanks!
Upvotes: 0
Views: 207
Reputation: 16920
You can iterate over the classes of an instance of your subclass. For example, suppose we have defined the following classes and methods:
foo <- function(x, ...) {
UseMethod("foo")
}
bar <- function(x) {
class(x) <- c("bar", class(x))
return(x)
}
baz <- function(x) {
class(x) <- c("baz", "bar", class(x))
return(x)
}
foo.bar <- function(x, ...) {
cat("Bar:", x, "\n")
}
foo.default <- function(x, ...) {
cat("Default:", x, "\n")
}
And we have created an instance of baz
, the subclass of bar
:
my_instance <- baz(1)
Now we could find all the callable methods, from baz
and the parent(s):
unname(unlist(sapply(class(my_instance), function(x) methods(class = x))))
[1] "foo.bar" "all.equal.numeric"
[3] "as.data.frame.numeric" "as.Date.numeric"
[5] "as.POSIXct.numeric" "as.POSIXlt.numeric"
[7] "as.raster.numeric" "coerce,ANY,numeric-method"
[9] "Ops,nonStructure,vector-method" "Ops,structure,vector-method"
[11] "Ops,vector,nonStructure-method" "Ops,vector,structure-method"
Now, calling them all is tougher, since they all have different arguments. Consider the following:
sapply(unlist(sapply(class(my_instance), function(x) methods(class = x))),
function(f) get(f)(my_instance, 2))
Bar: 1
Error in as.Date.numeric(origin, ...) : 'origin' must be supplied
Of course, we also probably need to eliminate things like "Ops,nonStructure,vector-method"
:
z <- unname(unlist(sapply(class(my_instance), function(x) methods(class = x))))
z[!grepl(",", z)]
[1] "foo.bar" "all.equal.numeric" "as.data.frame.numeric"
[4] "as.Date.numeric" "as.POSIXct.numeric" "as.POSIXlt.numeric"
[7] "as.raster.numeric"
Upvotes: 2