From jmc at r-project.org  Wed Apr 16 23:55:31 2008
From: jmc at r-project.org (John Chambers)
Date: Wed, 16 Apr 2008 14:55:31 -0700
Subject: [Rd] Pb with validObject(..., complete=TRUE)
In-Reply-To: <4804535C.7000307@fhcrc.org>
References: <4804535C.7000307@fhcrc.org>
Message-ID: <480675D3.3080503@r-project.org>

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
>
>



[Rd] Pb with validObject(..., complete=TRUE)
John Chambers