[Rd] Conflicting definitions for function redefined as S4 generics
Ulrich Bodenhofer
bodenhofer at bioinf.jku.at
Wed Mar 26 15:11:09 CET 2014
First of all, thanks for the very interesting and encouraging replies
that have been posted so far!
Let me quickly add what I have tried up to now:
- setMethod("sort", signature("ExClust"), function(x, decreasing=FALSE,
%...%) %...% , sealed=TRUE) without any call to setGeneric(), i.e.
assuming that setMethod() would implicitly create an S4 generic out of
the S3 method sort(). Note that '%...%' in the code snippet stands for
some details that I left out.
- setGeneric("sort", def=function(x, decreasing=FALSE, ...)
standardGeneric("sort")), i.e. consistency with the S3 generic of sort()
in 'base', plus the call to setMethod() as shown above.
- setGeneric("sort", signature="x"), i.e. consistency with the generic's
definition in BiocGenerics, as suggested by Martin Morgan, plus the call
to setMethod() as shown above.
For all three trials, the result was exactly the same: (1) everything
works nicely if I load BiocGenerics before apcluster; (2) if I load
BiocGenerics after apcluster, apcluster's sort() function is broken and
gives the following error:
Error in rank(x, ties.method = "min", na.last = "keep") :
unimplemented type 'list' in 'greater'
In addition: Warning message:
In is.na(x) : is.na() applied to non-(list or vector) of type 'S4'
Obviously, sort() is dispatched to the definition made by BiocGenerics:
> showMethods("sort", includeDefs=TRUE)
Function: sort (package BiocGenerics)
x="ANY"
function (x, decreasing = FALSE, ...)
{
if (!is.logical(decreasing) || length(decreasing) != 1L)
stop("'decreasing' must be a length-1 logical vector.\nDid you
intend to set 'partial'?")
UseMethod("sort")
}
So the method registered for class 'ExClust' is lost if BiocGenerics is
attached. Just for your information: all these tests have been done with
R 3.0.2 and Bioconductor 2.13 (BiocGenerics version 0.8.0).
Thanks and best regards,
Ulrich
On 03/26/2014 02:48 PM, Duncan Murdoch wrote:
> On 26/03/2014, 9:13 AM, Gabriel Becker wrote:
>> Perhaps a patch to R such that generics don't clobber each-other's
>> method
>> tables if the signatures agree? I haven't dug deeply, but simply merging
>> the method tables seems like it would be safe when there are no
>> conflicts.
>>
>> That way this type of multiplicity would not be a problem, though it
>> wouldn't help (as it shouldn't) if the two generics didn't agree on
>> signature or both carried methods for the same class signature.
>
> I don't think R should base the decision on the signature.
>
> There are two very different situations where this might come up. In
> one, package A and package B might both define a generic named foo()
> that happens to have the same signature, but with nothing in common.
> That should be allowed, and should behave the same as when they both
> create functions with the same name: it should be up to the user to
> specify which generic is being called. If R merged the two generics
> into one, there would be chaos.
>
> The other situation is more likely to apply to this case. It sounds
> as though both apcluster and BiocGenerics are creating a sort()
> generic by promoting the base package S3 generic into an S4 generic.
> Clearly they should not be creating separate generics, there's just one.
>
> I don't know if there's something wrong with the way apcluster or
> BiocGenerics are doing things, or something wrong with the way the
> methods package is creating the generic, but it sure looks like a bug
> somewhere.
>
> Duncan Murdoch
>
>>
>> ~G
>>
>>
>> On Wed, Mar 26, 2014 at 4:38 AM, Michael Lawrence
>> <lawrence.michael at gene.com
>>> wrote:
>>
>>> The BiocGenerics package was designed to solve this issue within
>>> Bioconductor. It wouldn't be the worst thing in the world to depend
>>> on the
>>> simple BiocGenerics package for now, but ideally the base generics
>>> would be
>>> defined higher up, perhaps in the methods package itself. Maybe someone
>>> else has a more creative solution, but any sort of conditional/dynamic
>>> approach would probably be too problematic in comparison.
>>>
>>> Michael
>>>
>>>
>>>
>>> On Wed, Mar 26, 2014 at 4:26 AM, Ulrich Bodenhofer <
>>> bodenhofer at bioinf.jku.at
>>>> wrote:
>>>
>>>> [cross-posted to R-devel and bioc-devel]
>>>>
>>>> Hi,
>>>>
>>>> I am trying to implement a 'sort' method in one of the CRAN
>>>> packages I am
>>>> maintaining ('apcluster'). I started with using setMethod("sort",
>>>> ...) in
>>>> my package, which worked fine. Since many users of my package are from
>>> the
>>>> bioinformatics field, I want to ensure that my package works smoothly
>>> with
>>>> Bioconductor. The problem is that the BiocGenerics package also
>>>> redefines
>>>> 'sort' as an S4 generic. If I load BiocGenerics before my package,
>>>> everything is fine. If I load BiocGeneric after I have loaded my
>>>> package,
>>>> my setMethod("sort", ...) is overridden by BiocGenerics and does
>>>> not work
>>>> anymore. A simple solution would be to import BiocGenerics in my
>>>> package,
>>>> but I do not want this, since many of this package's users are outside
>>> the
>>>> bioinformatics domain. Moreover, I am reluctant to include a
>>>> dependency
>>> to
>>>> a Bioconductor package in a CRAN package. I thought that maybe I could
>>>> protect my setMethod("sort", ...) from being overridden by
>>>> BiocGeneric by
>>>> sealed=TRUE, but that did not work either. Any ideas are gratefully
>>>> appreciated!
>>>>
>>>> Thanks a lot,
>>>> Ulrich
More information about the R-devel
mailing list