Thank you for the explanation; I saw that class definitions were stored in package-level .__C__* and in a global cache methods:::.classTable, but was not sure which was meant to be definitive.
I'm hoping your bug fix will address identically named sealed classes in different packages -- I hope to use 'sealed' as a way to reduce programming errors associated with unintentionally overwriting existing class definitions (the classes are generated programmatically, and a name conflict escaped my notice; I thought a 'better practice' would be to seal class definitions that I did not intend to change). The class hierarchies I am working with are large. I hope to avoid regenerating them each time the package is loaded, e.g., using a lazy load data base built when the package is installed. I can see how this might work when class definitions are in package-level variables .__C__*, but am less clear about how lazy loaded class definitions might be added to a globally cached class table. My more ambitious hope is to manage identically named classes from separate hierarchies in the same package, e.g., by placing each hierarchy in a separate environment (with attribute 'name' set, so environmentName() returns something sensible). I realize this does not work with the current implementation, but offer it as a potential use case. Thank you again for your help. Martin John Chambers <[EMAIL PROTECTED]> writes: > 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" >> class(x3) > [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 > > > -- Martin Morgan Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M2 B169 Phone: (206) 667-2793 ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel