Wacek Kusnierczyk <waclaw.marcin.kusnierc...@idi.ntnu.no> writes: > Martin Morgan wrote: >> Hi Vitalie -- >> >> Vitalie S. wrote: >> >>> Dear UseRs, >>> >>> A simple class inheritance example: >>> >>> >>>> setClass("test",representation(a="numeric")) >>>> setMethod("initialize","test", >>>> >>> function(.Object,x,...){ >>> print("Initialization!!!") >>> callNextMethod(.Object,a=x,...) >>> }) >>> >>> >>>> new("test",x=23) >>>> >>> [1] "Initialization!!!" >>> An object of class "test" >>> Slot "a": >>> [1] 23 >>> >> >> the implicit contract is that the initialize method is written so that >> new("test") works. This contract comes up at several points during class >> definition and instantiation. You've identified one of those points. >> >> >>>> setClass("test2",contains="test",representation(b="integer")) >>>> >>> [1] "Initialization!!!" >>> Error in .nextMethod(.Object, a = x, ...) : argument "x" is missing, >>> with no default >>> >> >> I'm not sure of the details, but part of the class definition is a >> coercion method, and in defining this new() is called, without >> arguments, on the contained classes. >> > > it sounds approximately ok that defining a subclass fails if its > initalizer does not provide a value required by the initializer of the > superclass. pardon me my ignorance, but here's an obvious question: > what if i *do* want to extend a class that has an initializer with an > argument without a default? (it does not seem to be a particularly > extravagant idea, does it?) i can't define the subclass with setClass, > because it fails, as above, due to a violation of the contract. but i
I'm speaking as a user, so my understanding is not meant to be definitive. I'd say the class with the intializer with an argument without a default is broken, and you should not want to extend it. > can't define an appropriate initializer for the subclass that would > fulfil the contract before i define the subclass itself. deadlock? > there is another quirk here, or -- in case the above is not a quirk -- > there is a quirk here. imagine i want to implement a class that counts > its instances as they are created, assigning to each a unique identifier remembering that R has copy-on-change semantics that are only approximately adhered to (e.g., some copying even without change), this objective would not likely be useful, e.g., it would not be a good identifier to know that you were dealing with the 'same' instance, and it would not be the way you'd want to track references for garbage collection or other clean-up, for instance. > from a contiguous sequence of integers, starting at 1 (this doesn't seem > to be a particularly extravagant idea either): > > setClass('foo', representation(id='integer')) > setMethod('initialize', 'foo', local({ > id=0L > function(.Object, ...) { > id <<- id+1L > .obj...@id = id > return(.Object) } })) > > foos = replicate(3, new('foo')) > sapply(foos, slot, 'id') > # 1 2 3 > > setClass('bar', contains='foo', representation(name='character')) > setMethod('initialize', 'bar', function(.Object, name='bar', ...) { > .obj...@name = name > callNextMethod() }) > bars = replicate(3, new('bar')) > sapply(bars, slot, 'id') > # 6 7 8 > > what?? why on earth creating a subclass *calls* (twice!) the > superclass's initializer? is there no other way for checking the once when the superclass is instantiated (fair enough!) and once when the validity of the subclass is checked -- the way that valildity checking works is that subclass is validated according to the subclass validity method, then the subclass is coerced to the superclass, and the superclass is checked for validity. The user can define the coerce method, but the default, for class hierarchies where it is appropriate, involves a call to new(), and hence to initialize and validObject. > setClass("A") [1] "A" > setClass("B", contains="A", representation(y="numeric")) [1] "B" > b <- as(new("B"), "A") > showMethods(coerce, class="B", includeDef=TRUE) Function: coerce (package methods) from="B", to="A" function (from, to = "A", strict = TRUE) if (strict) { value <- new("A") for (what in "x") slot(value, what) <- slot(from, what) value } else from Martin -- Martin Morgan Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793 ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.