The "infelicity" arises because validObject() is not a generic
function;
validity "method" is a bit of a misnomer. 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.
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
>
>