[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