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

Attachment: 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

Reply via email to