[R] S4: When is validObject issued? (or why S4 is killing me:( ..

Martin Morgan mtmorgan at fhcrc.org
Sat Jun 6 17:39:25 CEST 2009


Vitalie S. wrote:
> 
>>>
>>>  setMethod("initialize","test2",
>>>            function(.Object,...){
>>>                .Object<-callNextMethod(.Object,...)
>>
>> validity is checked in the preceeding line
>>
>>>                .Object at b<-.Object at a   ## here "b" is initialized ##
>>>
>>>                .Object
>>>            })
>>>
>>>> new("test2")
>>> Error in if (object at a != object at b) print("values must be equal!!")
>>> else TRUE : argument is of length zero
>>>
>>> This could mean only one thing, validity of "test2" is checked before
>>> it gets to point when b is initialized (i.e. in callNextMethod). But
>>> this is absurd (at leas from my point): callNextMethod constructs
>>> object of type "test" and should have nothing to do with validity of
>>> "test2". Shouldn't validity be checked only after the object is
>>> created?
>>
>> The class of .Object is test2, and initialize should return a (valid)
>> instance of test2, right? So the validity check on test2 has to have
>> been performed before returning from callNextMethod.
>>
> 
> Oh yes, that is indeed meaningful. So it's default coercion method from
> test1 to test2 which is called.
> 
>>> Second my slot "a" is initialized in "test1"'s constructor and "b"
>>> must be assigned only after the callNextMethod as in above
>>> code. Seemingly unsolvable paradox? How to be?
>>
>> My own solution would avoid using initialize (because as you're
>> discovering the contract is hard to satisfy in general) and instead
>> use constructors
> 
> I am sure this "contract" and all this
> initialization/coercion/creation-sequence  stuff must be documented
> somewhere. Though all what I can find is a collection of your responses
> in R-help archive. Could you please suggest something to read (except
> R-core code)?

?Methods and its 'References' and 'See also' section. Also, please take
my explanations with a grain of salt -- it represents my understanding,
not the way things are intended to be. Martin

> 
> 
> For now I am pretty much clarified. Thanks a lot!
> 
>>   test2 <- function(a=runif(1), b=a, ...) new("test2", a=a, b=b, ...)
>>
>> or similar, which I think helps to provide a bit of an interface
>> between the class and it's implementation.
>>
>> One could think of additional solutions (creating a new 'test' inside
>> 'test2', and not using callNextMethod(), for instance) but this is
>> unlikely to be robust (e.g., when derived classes are relying on
>> initialize,ANY-method to fill in slots with supplied arguments).
>>
>> Martin
>>
>>>
>>> Many thanks.
>>>
>>> ______________________________________________
>>> R-help at 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.
>>




More information about the R-help mailing list