What is a good way of defining a general purpose function which should have implementations for both S3 and S4 classes? I have been using something like this:
setGeneric("myfun", function(x, ...){
standardGeneric("myfun");
});
setMethod("myfun", "ANY", function(x, ...) {
if(!isS4(x)) {
return(UseMethod("myfun"));
}
stop("No implementation found for class: ", class(x));
});
This succeeds:
myfun.bar <- function(x, ...){
return("Object of class bar successfully dispatched.");
}
object <- structure(123, class=c("foo", "bar"));
myfun(object)
Is there a move "native" way to accomplish this? I know we can define S4 methods for S3 classes using setOldClass
, however this way we lose the S3 method dispatching in case an object has multiple classes. E.g. (in a clean session):
setGeneric("myfun", function(x, ...){
standardGeneric("myfun");
});
setOldClass("bar")
setMethod("myfun", "bar", function(x, ...){
return("Object of class bar successfully dispatched.");
});
object <- structure(123, class=c("foo", "bar"));
myfun(object)
This fails because the second class of object
, in this case bar
, is ignored. We could probably fix this by defining formal S4 inheritance between foo
and bar
, but for my application I would rather want myfun.bar
to work out of the box on S3 objects with a class bar
.
Either way, things are getting messy, and I guess this is a common problem, so there are probably better ways to do this?