Hi Ivan, Thanks for the careful investigation. I didn't notice that tidy was masked!
I expected that a delayed registration could prevent the error. But I think I made a bad decision when I defined tidy and I will probably change the method name. But I'll talk with Bioconductor people, for advice to see what can be done. I don't think when BiocGenerics depended on generics they accounted for this kind of breakage or informed their reverse dependencies. Many thanks for your help. On Sat, 8 Feb 2025 at 21:07, Ivan Krylov <ikry...@disroot.org> wrote: > В Sat, 8 Feb 2025 19:18:59 +0100 > Lluís Revilla <lluis.revi...@gmail.com> пишет: > > > Error in UseMethod("tidy") : no applicable method for 'tidy' applied > > to an object of class "GeneSet" > > This seems to be a distant consequence of > <https://github.com/Bioconductor/BiocGenerics/issues/20>. > > The example for BaseSet::tidy starts with > > >> if (requireNamespace("GSEABase", quietly = TRUE)) { > > which produces the following messages: > > Loading required package: BiocGenerics > Loading required package: generics > Attaching package: ‘generics’ > The following objects are masked from ‘package:BaseSet’: > tidy, union # <-- BaseSet::tidy now shadowed > > Indeed, at the point of the error, 'tidy' is > > Browse[1]> tidy > function (x, ...) > { > UseMethod("tidy") > } > <bytecode: 0x5615feed95c0> > <environment: namespace:generics> > > ...which is different from your own 'tidy' generic: > > Browse[1]> BaseSet::tidy > function (object) > { > UseMethod("tidy") > } > <bytecode: 0x5615eed320c8> > <environment: namespace:BaseSet> > > ...and the method is registered for the BaseSet::tidy generic, not the > generics::tidy generic: > > Browse[1]> 'tidy.GeneSet' %in% ls(BaseSet:::.__S3MethodsTable__.) > [1] TRUE > Browse[1]> 'tidy.GeneSet' %in% ls(generics:::.__S3MethodsTable__.) > [1] FALSE > > The problem only appears on R-devel because only the development > version of 'BiocGenerics' has the Depends: relationship with 'generics'. > > This one is easier to diagnose than to cure. The example seems to work > fine if the methods are registered for the other generic at runtime: > > library(BaseSet) > # these are undocumented, use .S3method() in more normal circumstances > registerS3method("tidy", "GeneSet", BaseSet:::tidy.GeneSet, > loadNamespace("generics")) > registerS3method("tidy", "GeneSetCollection", > BaseSet:::tidy.GeneSetCollection, > loadNamespace("generics")) > example("tidy") # doesn't crash > > Since BaseSet depends on a new enough R version, it could in theory use > delayed S3 method registration in its NAMESPACE file [1] in addition to > registering a method for BaseSet::tidy, but I think that you're now > expected to importFrom(generics, tidy) and export(tidy) to register S3 > methods on it. It's unfortunate that generics::tidy has a different > documented purpose. Perhaps the people better-versed in Bioconductor > have a better suggestion? > > Not sure where S4 method dispatch comes into play in your example, but > conditional import of S4 classes may be hard to implement. NAMESPACE > files use R syntax but different semantics. Testing for getRversion() > works because that doesn't usually change for the lifetime of the > package library. Testing for requireNamespace() wouldn't have worked > because the results are normally cached at installation time. Maybe > there's a way using load hooks, but we'd need an S4 wizard to implement > that correctly. Thankfully, 'BaseSet' seems to only call setMethod() > for its own classes, so there are no copies of foreign classes creating > binary dependencies in its namespace. > > -- > Best regards, > Ivan > > [1] > https://cran.r-project.org/doc/manuals/R-exts.html#Registering-S3-methods > [[alternative HTML version deleted]] ______________________________________________ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel