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.

Reply via email to