From hpages at fhcrc.org  Thu Apr 17 01:07:07 2008
From: hpages at fhcrc.org (Herve Pages)
Date: Wed, 16 Apr 2008 16:07:07 -0700
Subject: [Rd] Pb with validObject(..., complete=TRUE)
In-Reply-To: <480675D3.3080503@r-project.org>
References: <4804535C.7000307@fhcrc.org> <480675D3.3080503@r-project.org>
Message-ID: <4806869B.7080902@fhcrc.org>

Hi John,

John Chambers wrote:
> The "infelicity" arises because validObject() is not a generic function; 
> validity "method" is a bit of a misnomer.

Indeed. And I guess referring to "method dispatch" like I did in my previous
email is not appropriate either.
So yes I learned that thinking of validity "methods" as regular methods doesn't
really work. For example the man page for callNextMethod is stating that "a
call to 'callNextMethod' can only appear inside a method definition" but it
won't work inside a validity "method". Why would I need to do that? Well the
problem I reported in this thread can be worked around by redefining the
the same validity method for "PosInts2" objects as for "PosInts" objects.
So while I was looking at different ways to achieve this, I tried this
(I really want to avoid code duplication):

    setValidity("PosInts2", function(object) callNextMethod())

which of course doesn't work, so I finally came up with something like this:

    setValidity("PosInts2", getValidity(getClassDef(extends("PosInt2")[2])))

which tries to mimic what callNextMethod would do but in an ugly and easy to
break way. This is a temporary fix anyway, until validObject(..., complete=TRUE)
is fixed in R 2.8.0.

>  The functions are attached to 
> the class definition and validObject looks for them directly--in the 
> process it catches all methods from superclasses, but not from 
> superclasses of the slots' classes.
> 
> The fix is to call validObject recursively on each slot when 
> complete=TRUE.  This is a moderately large efficiency hit, but if you're 
> using complete=TRUE, it's reasonable to assume you really want the whole 
> truth, even if it takes a bit longer.

Absolutely.

Thanks for looking into this!

Cheers,
H.

> 
> Unless there are counter-arguments, we'll make this change (not, 
> however, for 2.7.0)
> 
> John
> 
> Herve Pages wrote:
>> Hi,
>>
>> When called with complete=TRUE, validObject() is supposed to work in a
>> recursive manner. But here is a situation where it doesn't seem to be
>> the case.
>>
>> Let's define a class with a validity method:
>>
>>    setClass("PosInts", representation(ii="integer"))
>>
>>    setValidity("PosInts",
>>      function(object)
>>      {
>>        if (!all(object at ii > 0))
>>          return("'ii' slot contains non-positive values")
>>        NULL
>>      }
>>    )
>>
>> Let's extend this class (no need to add new slots for illustrating the 
>> pb):
>>
>>    setClass("PosInts2", contains="PosInts")
>>
>>    broken <- new("PosInts2")
>>    broken at ii <- 3:0
>>
>> If "PosInts2" objects don't need to satisfy additional constraints in 
>> order to
>> be considered valid, then I don't need to define a validity method for 
>> them.
>> I can just rely on method dispatch, which works as expected with 
>> validity methods:
>>
>>    > validObject(broken)
>>    Error in validObject(broken) :
>>      invalid class "PosInts" object: 'ii' slot contains non-positive 
>> values
>>
>> Unfortunately, this will cause problems later when I try to validate 
>> objects
>> that have slots of type "PosInts2":
>>
>>    setClass("A", representation(aa="PosInts2"))
>>    a <- new("A", aa=broken)
>>
>> This works as expected:
>>
>>    > validObject(a)
>>    [1] TRUE
>>
>> But this is not what I would expect:
>>
>>    > validObject(a, complete=TRUE)
>>    [1] TRUE
>>
>> ... given that 'a' has a slot that contains an invalid "PosInts2" 
>> instance:
>>
>>    > validObject(a at aa)
>>    Error in validObject(a at aa) :
>>      invalid class "PosInts2" object: 'ii' slot contains non-positive 
>> values
>>
>> So clearly 'a' is broken and I would expect validObject(a, 
>> complete=TRUE) to
>> tell me so...
>>
>> Now if I define the same validity method for "PosInts2" objects as for 
>> "PosInts"
>> objects, then things work as expected (validObject(a, complete=TRUE) 
>> will fail)
>> but it's not clear to me why I should be forced to do this?
>>
>> Thanks!
>>
>> H.
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>   
>



[Rd] Pb with validObject(..., complete=TRUE)
Herve Pages