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 <ren...@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( obj...@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...@number <- 0
RG> a...@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...@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...@number <- -2
## Error in checkSlotAssignment .........
Regards,
Martin
RG> Thanks,
RG> Renaud
>> sessionInfo()
RG> R version 2.9.1 (2009-06-26)
..........
______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.