Let's start from a simpler description,? because the use of "sealed" adds some
confusion.? Here's a basic version. ? I have two packages, P2 and P3, with
different definitions of "myClass".
Classes with the same name on two packages are supposed to work, at least for
generating objects.? There is a bug (see below) and a workaround, but with or
without the workaround you need to apply new() to a class _object_, not just a
name, if you want to generate objects in the global environment.
Here's what currently works, using the workaround:
c2 = get(classMetaName("myClass"), envir = asNamespace("P2"))
c3 = get(classMetaName("myClass"), envir = asNamespace("P3"))
x2 = new(c2)
x3 = new(c3)
class(x2)
[1] "myClass"
attr(,"package")
[1] "P2"
[1] "myClass"
attr(,"package")
[1] "P3"
By using asNamespace(), it's not necessary to export the class definitions,
and possibly better not to.
Two comments:
- The bug is that you should be able to use
?? c2 = getClass("myClass", asNamespace("P2"))
instead of the call to get().? But a current misuse of cached definitions
means that only the first definition is known.? Hence the need for a
workaround using classMetaName() to get the class definition directly.? I
think the fix is easy & will try to add it to r-devel fairly soon.
- There are limitations to using duplicated class names, because not all
computations will carry the appropriate package information to say which
"myClass" we mean.? So if one can avoid duplicating class names, life will be
easier, and I suspect that duplicated classes that are _not_ exported will
work better, because computations will be forced into the individual
namespaces with less chance for getting the wrong definition.
Martin Morgan wrote:
I'd like to have two packages with S4 classes with the same name but
different implementation. To that end I create a package tmpA with
setClass("A",
representation=representation(
x="numeric"),
sealed=TRUE)
setClass("B",
representation=representation(
x="numeric"))
B <- function(...) new("B", ...)
and a NAMESPACE having only
import(methods)
export(B)
I duplicate this package source directory structure, renaming the
duplicate package tmpB in its Description file. After R CMD
INSTALL'ing both, I
library(tmpA)
library(tmpB)
Error in setClass("A", representation = representation(x = "numeric"), :
"A" has a sealed class definition and cannot be redefined
Error : unable to load R code in package 'tmpB'
Error: package/namespace load failed for 'tmpB'
setClass("A", prototype(y="numeric"))
Error in setClass("A", c(y = "numeric")) :
"A" has a sealed class definition and cannot be redefined
It appears that, although 'where' in setClass influences the location
of the class definition, there is a global class table that means only
one class of a particular name can ever be defined. Is that the
intended behavior?
If I create a class B in the global environment
setClass("B", representation(y="numeric"))
[1] "B"
and then use the constructor from tmpA, I end up with an instance of
the globally defined class B, rather than the one defined in the
constructor's name space:
B()
An object of class "B"
Slot "y":
numeric(0)
How would I write B to return an instance of B as defined in tmpA?
Thanks,
Martin
sessionInfo()
R version 2.7.0 Under development (unstable) (2008-02-09 r44397)
x86_64-unknown-linux-gnu
locale:
LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8;LC_COLLATE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_MESSAGES=en_US.UTF-8;LC_PAPER=en_US.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US.UTF-8;LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices datasets utils methods base
other attached packages:
[1] tmpA_1.0