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. > > > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel