[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