[Rd] Problem with S4 inheritance: unexpected re-initialization?
cstrato
cstrato at aon.at
Mon Apr 2 17:30:15 CEST 2007
Dear S4 experts,
Since I was reminded that I posted a similar question some time ago,
I am attaching a modified version of my demo package, which allows me
to track what happens during initialization of the following similar
subclasses:
SubSubClassA <- SubClassB <- BaseClass
SubSubClassB <- SubClassB <- BaseClass
First, I need to create SubClassA:
> library(myclasspkg)
> subA <-
new("SubClassA",filename="OutSubA",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",mytitle="TitleSubA")
Then, I create both subclasses, SubSubClassA and SubSubClassB, either
with a virtual BaseClass or with a non-virtual BaseClass:
1. new("SubSubClassA"): BaseClass is VIRTUAL
> subsubA <-
new("SubSubClassA",filename="MyFileName",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",subA=subA)
[1] "------initialize:SubSubClassA------"
[1] "------initialize:SubClassB------"
[1] "------initialize:BaseClass------"
[1] "------setValidity:BaseClass------"
[1] "------setValidity:SubClassB------"
[1] "------setValidity:SubSubClassA------"
As far as I understand the S4 classes, this is the correct initialization
workflow that I expect. The resulting object "subsubA" is correct.
However, when BaseClass is not virtual, I get the following unexpected
initialization workflow:
2. new("SubSubClassA"): BaseClass is NOT VIRTUAL
> subsubA <-
new("SubSubClassA",filename="MyFileName",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",subA=subA)
[1] "------initialize:SubSubClassA------"
[1] "------initialize:SubClassB------"
[1] "------initialize:BaseClass------"
[1] "------setValidity:BaseClass------" (called but NOT executed!)
[1] "------initialize:BaseClass------" (2.initialization, why?)
[1] "------setValidity:BaseClass------"
[1] "------setValidity:SubClassB------"
[1] "------setValidity:SubSubClassA------"
The first call to setValidity is not executed, and BaseClass is
initialized twice, the second time in a completely wrong way, which
normally results in an error. Interestingly, the resulting object
"subsubA" is still correct.
The results are completely different for SubSubClassB:
3. new("SubSubClassB"): BaseClass is VIRTUAL
> subsubB <-
new("SubSubClassB",filename="MyFileNameB",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",subA=subA)
[1] "------initialize:SubSubClassB------"
[1] "------initialize:SubClassB------"
[1] "------initialize:BaseClass------"
[1] "------setValidity:BaseClass------"
[1] "------initialize:SubClassB------"
[1] "------initialize:BaseClass------"
[1] "------initialize:SubClassA------"
[1] "------initialize:BaseClass------"
[1] "------setValidity:BaseClass------"
[1] "------setValidity:SubClassA------"
[1] "------setValidity:BaseClass------"
[1] "------setValidity:SubClassB------"
Error in validObject(.Object) : invalid class "SubClassB" object:
'filename' is missing
For some unknown reason SubClassA is initialized and BaseClass is
initialized three times. SetValidity is called until an error occurs.
Things get more weird when BaseClass is not virtal:
4. new("SubSubClassB"): BaseClass is NOT VIRTUAL
> subsubB <-
new("SubSubClassB",filename="MyFileNameB",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",subA=subA)
[1] "------initialize:SubSubClassB------"
[1] "------initialize:SubClassB------"
[1] "------initialize:BaseClass------"
[1] "------setValidity:BaseClass------"
[1] "------initialize:SubClassB------"
[1] "------initialize:BaseClass------"
[1] "------initialize:SubClassA------"
[1] "------initialize:BaseClass------"
[1] "------setValidity:BaseClass------"
[1] "------initialize:BaseClass------"
[1] "------setValidity:BaseClass------"
[1] "------setValidity:SubClassA------"
[1] "------setValidity:BaseClass------"
[1] "------initialize:BaseClass------"
[1] "------setValidity:BaseClass------"
[1] "------setValidity:SubClassB------"
Error in validObject(.Object) : invalid class "SubClassB" object:
'filename' is missing
It seems that initialization occurs in an endless cycle until an
error occurs.
Finally, let us look what happens when I follow the usual convention
where callNextMethod() is called first:
5. new("SubSubClassA"): callNextMethod() as 1.command; BaseClass is VIRTUAL
> subsubA <-
new("SubSubClassA",filename="MyFileName",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",subA=subA)
[1] "------initialize:SubSubClassA------"
[1] "------initialize:SubClassB------"
[1] "------initialize:BaseClass------"
The object "subsubA" is created correctly, however, setValidity()
is never called.
The same is true for SubSubClassB:
6. new("SubSubClassB"): callNextMethod() as 1.command; BaseClass is VIRTUAL
> subsubB <-
new("SubSubClassB",filename="MyFileNameB",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",subA=subA)
[1] "------initialize:SubSubClassB------"
[1] "------initialize:SubClassB------"
[1] "------initialize:BaseClass------"
The object "subsubB" is for the first time created correctly, however,
once again setValidity() is never called.
Maybe, I am misunderstanding an important part of creating S4 classes.
I would be really greatful, if the S4 experts could explain me what
happens here and what might be wrong with my demo package.
As a side note, when studying the code of the S4 packages "Biobase",
"affy" and "oligo", I made the observation, that none of these packages
calls "initialize" and "setValidity" for all classes and sub-classes.
Thank you very much in advance.
Best regards
Christian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: myclasspkg_0.1.1.tar.gz
Type: application/x-gzip
Size: 5523 bytes
Desc: not available
Url : https://stat.ethz.ch/pipermail/r-devel/attachments/20070402/17170514/attachment.gz
More information about the R-devel
mailing list