[R] Validity check when setting slot
Martin Maechler
maechler at stat.math.ethz.ch
Mon Aug 10 18:25:22 CEST 2009
>>>>> "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