[Rd] Pb with validObject(..., complete=TRUE)
hpages at fhcrc.org
Thu Apr 17 01:07:07 CEST 2008
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:
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.
Thanks for looking into this!
> Unless there are counter-arguments, we'll make this change (not,
> however, for 2.7.0)
> Herve Pages wrote:
>> 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"))
>> if (!all(object at ii > 0))
>> return("'ii' slot contains non-positive values")
>> Let's extend this class (no need to add new slots for illustrating the
>> 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
>> 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
>> Unfortunately, this will cause problems later when I try to validate
>> that have slots of type "PosInts2":
>> setClass("A", representation(aa="PosInts2"))
>> a <- new("A", aa=broken)
>> This works as expected:
>> > validObject(a)
>>  TRUE
>> But this is not what I would expect:
>> > validObject(a, complete=TRUE)
>>  TRUE
>> ... given that 'a' has a slot that contains an invalid "PosInts2"
>> > validObject(a at aa)
>> Error in validObject(a at aa) :
>> invalid class "PosInts2" object: 'ii' slot contains non-positive
>> 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
>> 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?
>> R-devel at r-project.org mailing list
More information about the R-devel