[Rd] Problem with S4 inheritance: unexpected re-initialization?

cstrato cstrato at aon.at
Fri Apr 6 21:37:53 CEST 2007


Dear Herve

Although I am currently learning to use S4 classes, and thus I am 
probably not the person
to comment on S4 classes, I completely agree with you.

Coming from C++ (most of my code is C++), this is what I have 
intuitively expected,
although I was not able to formulate it. I am glad that you did.

At the moment I try to find out if there is a possibility to circumvent 
this problem.
I do not know if there is a possibility to set an object to NULL 
initially, and then
call: "if (!is.null(object)) do something"

Best regards
Christian



Herve Pages wrote:
> Martin,
>
> Martin Morgan wrote:
>   
>> The funny effect where class(object) seems to trigger construction of
>> a new object is lazy evaluation -- the 'object' argument to
>> setValidity is not evaluated until needed, i.e., until class(object)
>> (anything would trigger this, including force(object)); only then do
>> you see the attempt to create the new object of the previous
>> paragraph.
>>     
>
> The fact that you can't predict the number of times the "initialize"
> method will be called is problematic. Here is a simple example
> where "initialize-A" increments a global counter to keep track of the
> number of A-objects:
>
>   A.GLOBALS <- new.env(parent=emptyenv())
>   A.GLOBALS[["nobjs"]] <- 0L
>
>   setClass("A",
>     representation(a="character"),
>     prototype(a="a0")
>   )
>   setMethod("initialize", "A",
>     function(.Object, ...) {
>         cat("------initialize:A------\n")
>         A.GLOBALS[["nobjs"]] <- A.GLOBALS[["nobjs"]] + 1
>         cat("A-object #", A.GLOBALS[["nobjs"]], "\n", sep="")
>         callNextMethod()
>     }
>   )
>   setValidity("A",
>     function(object) {
>         cat("------setValidity:A------\n")
>         tmp <- class(object)
>         TRUE
>     }
>   )
>
>   setClass("B",
>     contains="A",
>     representation(b = "character")
>   )
>   setMethod("initialize", "B",
>     function(.Object, ...) {
>         cat("------initialize:B------\n")
>         callNextMethod()
>     }
>   )
>   setValidity("B",
>     function(object) {
>         cat("------setValidity:B------\n")
>         TRUE
>     }
>   )
>
> Let's try it:
>
>   > b1 <- new("B")
>   ------initialize:B------
>   ------initialize:A------
>   A-object #1
>   > A.GLOBALS[["nobjs"]]
>   [1] 1
>
>   > b1 <- new("B", b="hello")
>   ------initialize:B------
>   ------initialize:A------
>   A-object #2
>   ------setValidity:A------
>   ------initialize:A------
>   A-object #3
>   ------setValidity:B------
>   > A.GLOBALS[["nobjs"]]
>   [1] 3
>
> Shouldn't the "initializing" ("constructor" in other languages) code be executed
> exactly 1 time per object instanciation? Something that the programmer can simply
> rely on, whatever this code contains and whatever the internal subtilities of the
> programming lamguage are?
>
> Cheers,
> H.
>
>
>
>



More information about the R-devel mailing list