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.mich...@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 <
bodenho...@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
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel