Martin Morgan
2012-Feb-26 17:19 UTC
[Rd] Comments on R_exts section 1.6.6, Namespaces with S4 classes and methods
> R.version.string[1] "R Under development (unstable) (2012-02-26 r58493)" In the recent addition "It is important if you export S4 methods that the corresponding generics are available: the requirementa on this are stricter as from R 2.15.0. You may for example need to import plot from graphics to make visible a function to be converted into its implicit generic. But it is better practice to make use of the generics exported by stats4 as this enables multiple packages to unambiguously set methods on those generics." (note typo on 'requirementa') I agree that existing generics should be reused. The advice points to a very unsatisfactory contortion -- use the generic from stats4 for a function in graphics! It is unclear whether the advice is 'use the implicit generic from stats4 whenever wanting to define an S4 method on graphics::plot' or 'if a package your package depends on creates a generic, use that generic instead of creating your own'. The former introduces artificial dependencies on stats4, the latter allows for several independently defined S4 generics on plot. Neither is satisfactory. Dozens of Bioconductor packages importFrom(graphics, plot) and exportMethods(plot), in addition to other common functions. Our solution has been to create a package BiocGenerics whose purpose is to create and document otherwise implicit generics of base packages (see ?BiocGenerics for a list of generics). Packages then Import: BiocGenerics and importFrom(BiocGenerics, plot). This kind of approach, whatever limitations of current implementation, seems much better, providing some consistency in documentation and application while limiting artificial dependencies (to just one, BiocGenerics). Is a methodsGenerics package in base R an appropriate direction? Somewhat earlier in section 1.6.6, the advice offered is "If the generic function is not local to this package, either because it was imported as a generic function or because the non-generic version has been made generic solely to add S4 methods to it (as for functions such as plot in the example above), it can be declared via either or both of export or exportMethods, but the latter is clearer (and is used in the stats4 example above)." I agree that for an explicit generic defined in another package it makes sense to exportMethods. When a package creates a generic (as stats4 does) the better advice is (a) to create an explicit generic via setGeneric("plot") (as stats4 does) and (b) to document and export the generic, as the generic has consequences above and beyond the method. Finally, primitive functions are currently singled out for special treatment in several sub-clauses of section 1.6.6. Aggregating these sub-clauses into a separate paragraph on primitives would be clearer. Martin -- Computational Biology Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: M1-B861 Telephone: 206 667-2793
Possibly Parallel Threads
- improved error message when existing implicit S4 generic is not imported?
- Conflicting definitions for function redefined as S4 generics
- [Bioc-devel] Conflicting definitions for function redefined as S4 generics
- Depot for S3 to S4 generics (as in stats4)?
- odd assignInNamespace / setGeneric interaction