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
myclasspkg_0.1.1.tar.gz
Description: GNU Zip compressed data
______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel