cstrato
2007-Mar-31 17:56 UTC
[Rd] Problem with S4 inheritance: unexpected re-initialization?
Dear all, To explain my problem I am attaching a demonstration package "myclasspkg": I have the following two S4 classes with similar inheritance: SubSubClassA <- SubClassB <- BaseClass SubSubClassB <- SubClassB <- BaseClass In R I am calling the following functions: > library(myclasspkg) > subA <- new("SubClassA",filename="OutSubA",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",mytitle="TitleSubA") > subsubA <- new("SubSubClassA",filename="MyFileName",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",subA=subA) > subsubB <- new("SubSubClassB",filename="MyFileNameB",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",subA=subA) Creating subsubA works fine and gives the correct result: > subsubA <- new("SubSubClassA",filename="MyFileName",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",subA=subA) [1] "------initialize:SubSubClassA------" [1] "SubSubClassA:init:class(.Object) = SubSubClassA" [1] "------initialize:SubClassB------" [1] "SubClassB:init:class(.Object) = SubSubClassA" [1] "------initialize:BaseClass------" [1] "BaseClass:init:class(.Object) = SubSubClassA" [1] "------pathFile------" [1] "BaseClass:init:dirfile = /Volumes/CoreData/CRAN/Workspaces/rclasspkg/MyFileName" [1] "------setValidity:BaseClass------" [1] "BaseClass:val:class(object) = SubClassB" [1] "BaseClass:val:dirfile = /Volumes/CoreData/CRAN/Workspaces/rclasspkg/MyFileName" [1] "BaseClass:val:filedir = /Volumes/CoreData/CRAN/Workspaces/rclasspkg" [1] "------setValidity:SubClassB------" [1] "SubClassB:val:class(object) = SubClassB" [1] "SubClassB:val:filename = MyFileName" [1] "BaseClass:val:dirfile = /Volumes/CoreData/CRAN/Workspaces/rclasspkg/MyFileName" [1] "------setValidity:SubSubClassA------" [1] "SubSubClassA:val:class(.Object) = SubSubClassA" In contrast, when trying to create subsubB, it seems that setValidity re-initializes SubClassB: > subsubB <- new("SubSubClassB",filename="MyFileNameB",filedir="/Volumes/CoreData/CRAN/Workspaces/rclasspkg",subA=subA) [1] "------initialize:SubSubClassB------" [1] "SubSubClassB:init:class(.Object) = SubSubClassB" [1] "SubSubClassB:init:subsubnameB = subsubNameB" [1] "------initialize:SubClassB------" [1] "SubClassB:init:class(.Object) = SubSubClassB" [1] "------initialize:BaseClass------" [1] "BaseClass:init:class(.Object) = SubSubClassB" [1] "------pathFile------" [1] "BaseClass:init:dirfile = /Volumes/CoreData/CRAN/Workspaces/rclasspkg/MyFileNameB" [1] "------setValidity:BaseClass------" [1] "------initialize:SubClassB------" [1] "SubClassB:init:class(.Object) = SubClassB" [1] "------initialize:BaseClass------" [1] "BaseClass:init:class(.Object) = SubClassB" [1] "------pathFile------" Error in if (dirname(filename) != ".") { : argument is of length zero Can someone tell me why the first case works fine, but the second case not? Probably, I am making some mistake, but since two weeks I am unable to find it. Thank you in advance. P.S.: I am running R-2.5.0 on Intel-Mac OS 10.4.8. Best regards Christian _._._._._._._._._._._._._._._._ C.h.i.s.t.i.a.n S.t.r.a.t.o.w.a V.i.e.n.n.a A.u.s.t.r.i.a _._._._._._._._._._._._._._._._ -------------- next part -------------- A non-text attachment was scrubbed... Name: myclasspkg_0.1.1.tar.gz Type: application/x-gzip Size: 5160 bytes Desc: not available Url : https://stat.ethz.ch/pipermail/r-devel/attachments/20070331/06308a2d/attachment.gz
cstrato
2007-Apr-02 15:30 UTC
[Rd] Problem with S4 inheritance: unexpected re-initialization?
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