[R] Validity check when setting slot

Renaud Gaujoux getoxxx at gmail.com
Mon Aug 10 19:10:06 CEST 2009


Hi Martin,

Indeed the validObject works, but I was expecting it to be called 
automatically after a slot assignment.
I understand the fact that during their construction, objects' slots are 
sometime not valid, and thought the check=FALSE was there for such cases.

My validity method needs to check the consistency of the slots together, 
not only the validity of a slot separately. So I need to have it defined 
within my bigger class (not at the slots level).
I can surely find a work around (eg. calling explicitly the validity 
method on the object before returning it) but I was wanting not to code 
it for each of my slots (lazy me :D). That's fine, I'll do that.

Thanks,
Renaud

Martin Maechler wrote:
>>>>>> "RG" == Renaud Gaujoux <renaud at mancala.cbio.uct.ac.za>
>>>>>>     on Mon, 10 Aug 2009 17:19:12 +0200 (SAST) writes:
>>>>>>             
>
>     RG> Hi,
>     RG> I'm wondering if the following behaviour is normal:
>
>     RG> setClass('A', representation(number='numeric'), 
>     RG> validity=function(object){ 
>     RG> if( object at number < -1 ) return("Invalid number"); TRUE})
>     >> [1] "A"
>     RG> a <- new('A')
>     RG> a
>     >> An object of class “A”
>     >> Slot "number":
>     >> numeric(0)
>
>     RG> a at number <- 0
>     RG> a at number <- -3
>     RG> a
>     >> An object of class “A”
>     >> Slot "number":
>     >> [1] -3
>
> However, note that
>
>  > validObject(a)
>  Error in validObject(a) : invalid class "A" object: Invalid number
>
> and also
>
>  > a at number <- "foo"
>  Error in checkSlotAssignment(object, name, value) : 
>    assignment of an object of class "character" is not valid for slot "number" in an object of class "A"; is(value, "numeric") is not TRUE
>  Calls: @<- -> slot<- -> checkSlotAssignment
>
>
>
>     RG> So: the slot is set to an invalid value according to the validity method 
>     RG> and nothing happens (no error) whereas the doc says:
>
>     RG> "The replacement forms do check (except for
>     RG> 'slot' in the case 'check=FALSE').  So long as slots are set
>     RG> without cheating, the extracted slots will be valid."
>
> hmm, I don't where that part is cited from,
> but yes, the above *is* correct behavior.
>
> Why?
> Well, several reasons:
> 1)  slot assignment must be reasonably efficient, as it is an
>    "atomic" part of building up high level objects
>     ==> only the *class* of the slot is checked, but not the
>     validity method of the container.
> 2) During the incremental build-up of an S4 object (with several
>    slots), the object itself is often not "valid"; it would be
>    bad, if slot-assignment triggered "upper-level" validity checking.
>
>
> If you really want what you want (:-),
> use something like
>
> setClass("posNumber", contains = "numeric",
>          validity = function(object) {
>              if(object <= 0) return("Not a positive number")
>              TRUE
>          })
>
> setClass('B', representation(number= 'posNumber'))
>
> (b <- new("B", number = new("posNumber",pi)))
> ## An object of class 'B'
> ## Slot "number":
> ## An object of class 'posNumber'
> ## [1] 3.141593
>
> b at number <- -2
> ## Error in checkSlotAssignment .........
>
>
> Regards,
> Martin
>
>     RG> Thanks,
>     RG> Renaud
>
>     >> sessionInfo()
>     RG> R version 2.9.1 (2009-06-26) 
>     ..........
>




More information about the R-help mailing list