Re: [Rd] S4 classes and methods with optional arguments

From: Seth Falcon <sfalcon_at_fhcrc.org>
Date: Tue 14 Feb 2006 - 16:22:04 GMT

Hi Josef,

On 14 Feb 2006, leydold@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



R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Wed Feb 15 04:06:31 2006

This archive was generated by hypermail 2.1.8 : Wed 15 Feb 2006 - 06:37:18 GMT