[Phylobase-devl] setGeneric vs. setMethod

Peter Cowan pdc at berkeley.edu
Wed Jun 25 07:00:21 CEST 2008


On Mon, Jun 23, 2008 at 5:44 AM, Thibaut Jombart
<jombart at biomserv.univ-lyon1.fr> wrote:
> Peter Cowan wrote:
>>
>> Hey all,
>>
>> I'd like to add a new generic 'reorder'.  I was looking through the
>> generics and methods and is appears that for each function we each.
>> For example the generic "hasNodeLabels" is coded in the following way.
>>
>> In methods-phylo4.R there exists:
>>
>> setMethod("hasNodeLabels", "phylo4", function(x) {
>>    length(x at node.label) > 0
>> })
>>
>> In the phylo4.R there exists:
>>
>> setGeneric("hasNodeLabels", function(x) {
>>    standardGeneric("hasNodeLabels")
>> })
>>
>>
>> My understanding is that the setGeneric calls the method
>> standardGeneric() to define the function.  However, my understanding
>> is that these doesn't set the default, it uses the previously set
>> 'hasNodeLabels'.  My question is why do we set Generics in this
>> manner?  Couldn't we also do:
>>
>> setGeneric("hasNodeLabels", useAsDefault = function(x) {
>>    length(x at node.label) > 0
>> })
>>
>> (maybe also setting the group parameter, which I don't quite grok)
>>
>> Thanks
>>
>> Peter
>> _______________________________________________
>> Phylobase-devl mailing list
>> Phylobase-devl at lists.r-forge.r-project.org
>>
>> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/phylobase-devl
>>
>>
>>
>
> Hi Peter,
>
> I think the call to standardGeneric is required to set the dispatcher on,
> that is, to be sure that the right method is used with the right signature.
> I think useAsDefault can be used together with it:
>
> ## set a generic
> setGeneric("giveAnInt",
>   def=function(x) { standardGeneric("giveAnInt") },
>   useAsDefault=function(x){
>       if(is.integer(x)) return(x) else return(0)})
>
> ## set a method for characters, that return NA
> setMethod("giveAnInt", "character", function(x) {return(NA)})
>
> ## give it a try
>> giveAnInt(1.1)
> [1] 0
>> giveAnInt(as.integer(2))
> [1] 2
>> giveAnInt("toto")
> [1] NA
>
> ## all works as expected ##
>
> Now try this (the version you mentionned):
>> setGeneric("giveAnInt",
>   def=function(x) {
>       if(is.integer(x)) return(x) else return(0)})
>
> Warning message: ## warning is explicit enough ...
> In .NonstandardGenericTest(body(fdef), name, stdGenericBody) :
>  the supplied generic function definition for giveAnInt does not seem to
> call 'standardGeneric'; no methods will be dispatched!
> ## ... but still we try
>> setMethod("giveAnInt", "character", function(x) {return(NA)})
> [1] "giveAnInt"
>> giveAnInt("toto")
> [1] 0
>
> ## no dispatching !

Thanks Thibaut for that explanation.  It is all much clearer now, I
still don't understand what the group argument to setGeneric() does,
but perhaps I have to find a copy of the green book.

If there aren't objections at some point I'd like to combine the pile
of methods and generics we have into single setGeneric() calls.  As I
mentioned we have a setMethod and setGeneric for hasNodeLabels.  I'll
do a bit more testing, but is there any reason not to tidy up the code
in this way?

Peter


More information about the Phylobase-devl mailing list