I guess the appropriate way is to use "ANY" in the signature:
setGeneric("foo",function(x) standardGeneric("foo"))
setMethod("foo","numeric",function(x) "numeric")
setMethod("foo","ANY",function(x) "ANY")
> foo(1)
[1] "numeric"
> foo()
[1] "ANY"
> foo(NULL)
[1] "ANY"
Make sure you specify every other possibility that you want taken care of, as "ANY" also takes all the rest that doesn't fit to the signature of another method.
If you have arguments that can be missing, you can just not specify them in the signature of setMethods and set a default in the generic. This is -in my humble view- a better design choice.
setGeneric("foo",function(x,y=NULL,...) {
standardGeneric("foo")
})
setMethod("foo",c("numeric","ANY"),function(x,y,...) {
print(y)
})
setMethod("foo",c("numeric","numeric"),function(x,y,...) {
x + y
})
> foo(1)
NULL
> foo(1,3)
[1] 4
> foo(1,NULL)
NULL
Now you can deal with the NULL cases in-code like you would do with the missing arguments.
On a sidenote: Now I added NULL as default value, but in many cases there are far more sensible choices for default values. Just remember that the setMethod takes the initial signature, and that when y is set as NULL, this is not replaced by the default.
eg:
setGeneric("bar",function(x,y=2,...) {
standardGeneric("bar")
})
setMethod("bar",c("numeric","ANY"),function(x,y,...) {
x + y
})
setMethod("bar",c("numeric","numeric"),function(x,y,...) {
x - y
})
> bar(1)
[1] 3
> bar(1,2)
[1] -1
> bar(1,NULL) # this y is not replaced with the default!
numeric(0)
DIRTY HACK :
I find the approach a bit awkward, but here is a dirty hack that sets all missing parameters to NULL :
setGeneric("foo",function(x,y,z) {
pars <- names(formals(foo))
for(i in pars){
tryerr <- try(get(i),silent=T)
if(is(tryerr,"try-error")){ assign(i,NULL)}
}
standardGeneric("foo")
}
Trying this, you get :
> foo(1)
[1] "numeric"
> foo(NULL)
[1] "NULL"
> foo()
[1] "NULL"
So you never dispatch to the missing any more. You can just forget about it. But this ain't the appropriate way of doing things...