[Bioc-devel] Extend class definition on attaching a package
On 08/26/2010 05:58 PM, Venkatraman Seshan wrote:
Thanks Martin. I was probably making it more complicated than it needed to
be. I just want to load bigmemory package (if it is installed) and redefine
the classes. I followed your advice and now AllClasses.R is
setClassUnion("mymatrix", c("mymatrix"))
setClass("mydata", representation(x="numeric", y="cnmatrix"))
and zzz.R is
.onLoad <- function(libname, pkgname) {
bigmem <-
suppressWarnings(suppressPackageStartupMessages(require(bigmemory)))
if (bigmem) {
setClassUnion("cnmatrix", c("matrix", "big.matrix"))
setClass("mydata", representation(x="numeric", y="cnmatrix"))
}}
Now it seems to work but I get the following warning message both on R CMD
check and loading the package within R
Class "big.matrix" is defined (with package slot bigmemory) but no metadata
object found to revise superClass information---not exported? Making a copy
in package foo
I assume it is because NAMESPACE doesn't have importClasseFrom(bigmemory,
big.matrix)
Is there a way I can change the NAMESPACE (in .onLoad or elsewhere)?
I guess you're trying to develop a package that has functionality that
has code that is conditional on the bigmemory package -- if bigmemory is
available then do one thing, otherwise do another. But this is not, in
my opinion, a good idea -- your user gets different behavior on Monday
versus Wednesday (because they installed bigmemory on Tuesday) and you
have two code branches to maintain (which leads to headaches, as
evidenced by this thread!). So I think you really just want to
Imports: bigmemmory
in your DESCRIPTION file,
importClassesFrom(bigmemory, big.matrix)
in NAMESPACE
and
setClassUnion("cnmatrix", c("matrix", "big.matrix"))
setClass("mydata",
representation=representation(x="numeric", y="cnmatrix"))
in the 'top level' (i.e., not in .onLoad or other function call) of some
R/*R file.
Actually my stronger advice is that you avoid the setClassUnion --
you're really saying that your 'cnmatrix' walks and talks exactly like a
matrix and a big.matrix, and vice versa, when really you have no control
over what methods are defined for matrix or big.matrix (any package can
define methods for these classes) so you have no idea whether the
methods are appropriate for cnmatrix. Better in my opinion to implement
the interface that is directly relevant to cnmatrix, even if it is often
simple delegation to a 'matrix' slot of cnmatrix.
Martin
Thanks again, Venkat On Thu, Aug 26, 2010 at 7:58 PM, Martin Morgan <mtmorgan at fhcrc.org> wrote:
On 08/26/2010 12:58 PM, Venkatraman Seshan wrote:
In AllClasses.R I used
setClassUnion("cnmatrix", c("matrix"))
Sorry for the typo.
Venkat
On Thu, Aug 26, 2010 at 3:31 PM, Venkatraman Seshan <veseshan at gmail.com
wrote:
Can the class definition in package "foo" be changed after the package
is
attached? I am trying to do the following.
The AllClasses.R file has the following class definitions.
setClassUnion("mymatrix", c("mymatrix"))
setClass("mydata", representation(x="numeric", y="cnmatrix"))
In zzz.R the .onLoad has the following:
setHook(packageEvent("bigmemory", "attach"),
function(...){
setIs("big.matrix", "cnmatrix")
setClass("mydata", representation(x="numeric", y="cnmatrix")
})
When I now do R CMD check pkg it is completed but I get a note
* checking R code for possible problems ... NOTE
Error in setIs("big.matrix", "cnmatrix") :
cannot create a 'setIs' relation when neither of the classes
("big.matrix" and "cnmatrix") is local and modifiable in this package
How do I modify the definition of a class in a package?
Hi Venkat -- not really answering your question, but I don't really think you want to do either setClassUnion or setIs -- inheritance is difficult enough to understand without adding novel relationships between classes. And I don't think you really want to conditionally define class relationships on package load either (which I is guess what setHook(packageEvent()) accomplishes; I've never seen that before); these all sound like you're making trouble for yourself (and users of your package) in the future. But... .onLoad is run after Import: and Depend: packages have been loaded, and before the name space of the package in which .onLoad is defined is 'sealed'. I think this means that if you had Import'ed or Depend'ed on bigmemory, then a setIs and setClass in .onLoad (not setHook(...)) would be successful, just as
library(bigmemory)
setClassUnion("cnmatrix", "matrix")
[1] "cnmatrix"
setIs("big.matrix", "cnmatrix")
setClass("mydata", representation(x="numeric", y="cnmatrix"))
[1] "mydata"
are successful when run in an R session.
So I guess what happens is the 'packageEvent' isn't actually evaluated
in .onLoad, but afterward, when bigmemory is loaded (by some other code
in your package? I'm not understanding how R CMD check is detecting the
error) and your name space has already been sealed (which occurs after
the .onLoad hook runs) and is therefore not modifiable. Maybe you could
create an environment in your package
.secrets <- new.env(parent=emptyenv())
setPackageName("MyPackage", .secrets)
and place your class definition there
setClass("cnmatrix", where=.secrets)
.secrets isn't sealed, so the class definition might still be
modifiable. I really don't know how this would work, e.g., exporting
cnmatrix from your package name space, invoking methods, etc., or
whether it would provide a way to modify the class definition once the
name space is sealed. My little experiments suggest that you can create
an instance with
new(getClassDef("cnmatrix", where=MyPackage:::.secrets))
or by
attach(MyPackage:::.secrets, name="search")
new("MyClass")
and create a setIs relationship, without generating errors or warnings,
with
attach(MyPackage:::.secrets, name="secrets")
setIs("big.matrix", "cnmatrix", where="secrets")
detach("secrets")
but all of this seems like a big hack.
Martin
Thanks, Venkat My R.Version() $platform [1] "x86_64-pc-linux-gnu" $arch [1] "x86_64" $os [1] "linux-gnu" $system [1] "x86_64, linux-gnu" $status [1] "" $major [1] "2" $minor [1] "11.1" $year [1] "2010" $month [1] "05" $day [1] "31" $`svn rev` [1] "52157" $language [1] "R" $version.string [1] "R version 2.11.1 (2010-05-31)"
[[alternative HTML version deleted]]
_______________________________________________ Bioc-devel at stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/bioc-devel
-- Martin Morgan Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793
Martin Morgan Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793