[Rd] S4 classes and methods with optional arguments
Seth Falcon
sfalcon at fhcrc.org
Tue Feb 14 17:22:04 CET 2006
Hi Josef,
On 14 Feb 2006, leydold at statistik.wu-wien.ac.at wrote:
> I have used a construct to allow optional arguments:
>
> if(!isGeneric("rstream.sample")) setGeneric("rstream.sample",
> function(stream,...) standardGeneric("rstream.sample"))
First, a question:
Is this idiom of testing for the generic before defining it still
"recommended"? It seems to me that one should either define one's
own generic in the package namespace or define a method for a
*particular* generic defined elsewhere. Otherwise, one could end up
defining a method for the wrong generic.
> setMethod("rstream.sample", c("rstream","numeric"),
> function(stream,n=1) { ... [ code ] ... } )
This will work if you remove the second arg in the signature. That
is,
setMethod("rstream.sample", signature(stream="rstream"),
function(strea, n=1) { ... })
Putting an arg in the signature means dispatching on that arg. You
cannot dispatch on an arg that is not named in the definition of the
generic.
> however, with R-devel the above construct does not work any more,
> due to more stringent checkings. It can be fixed by replacing it by
>
> if(!isGeneric("rstream.sample")) setGeneric("rstream.sample",
> function(stream,n) standardGeneric("rstream.sample"))
>
> setMethod("rstream.sample", c("rstream","numeric"),
> function(stream,n=1) { ... [ code ] ... } )
>
> then rstream.sample(rs) does not work any more.
>
> Is there still a way to allow optional arguments for methods of S4
> classes?
Here's an approach that works for me:
1. You have to specify a default value to args *in the generic*. This
doesn't make a whole lot of sense to me, but it does seem to be
needed.
setGeneric("rstream.sample",
function(stream, n=0) standardGeneric("rstream.sample"))
2. Then define a method with a signature that matches the default
case:
setMethod("rstream.sample", signature(stream="rstream", n="missing"),
function(stream, n=1) { ... })
Note that you could also use signature(stream="rstream"), but then
a call like rstream.sample(s, "foo") could match... Leaving out the
arg is like saying n="ANY".
HTH,
+ seth
More information about the R-devel
mailing list