[R] initalizing and checking validity of S4 classes

Martin Morgan mtmorgan at fhcrc.org
Wed Jul 25 03:39:42 CEST 2007


Hi Michal --

Add validObject to your initialize method:

> setMethod("initialize", "someclass",
+ function(.Object, v=numeric(0), l=character(0))
+ {
+     # strip the vector names
+     cv <- v
+     cl <- l
+     names(cv) <- NULL
+     names(cl) <- NULL
+     rval <- .Object
+     rval at v <- cv
+     rval at l <- cl
+     validObject(rval)
+     rval
+ } )
[1] "initialize"
> new("someclass", v=1:2, l=letters[1:3])
Error in validObject(rval) : 
  invalid class "someclass" object: lengths dont match

Note that without initialize, we have:

> setClass("A",
+          representation=representation(
+            v="numeric", l="character"))
[1] "A"
> setValidity("A", f)

Slots:
                          
Name:          v         l
Class:   numeric character
> new("A", v=1:2, l=letters[1:3])            
Error in validObject(.Object) : 
  invalid class "A" object: lengths dont match
 
Here are two interpretations of this. (1) using 'initialize' means
that you are taking control of the initialization process, and hence
know when you need to call validObject. (2) Responsibility for object
validity is ambiguous -- does it belong with 'new', 'initialize', or a
'constructor' that the programmer might write? This is particularly
problematic with R's copy semantics, where creating transiently
invalid objects seems to be almost necessary (e.g., callNextMethod()
in 'initialize' might initialize the inherited slots of the object,
but the object itself is of the derived class and could well be
invalid 'invalid' after the base class has finished with initialize).

Martin

"Bojanowski, M.J.  (Michal)" <M.J.Bojanowski at uu.nl> writes:

> Dear useRs and wizaRds,
>
> I am currently developing a set of functions using S4 classes. On the way I encountered the problem exemplified with the code below. For some reason the 'validity' method does not seem to work, i.e. does not check for errors in the specification of the slots of the defined class. Any hints?
>
> My understanding of the whole S4 system was that validity checks are made *after* class initialization. Is that correct?
>
> Thanks a lot in advance!
>
> PS. Session info:
>
> R version 2.5.1 (2007-06-27) 
> i386-pc-mingw32 
>
> locale:
> LC_COLLATE=Polish_Poland.1250;LC_CTYPE=Polish_Poland.1250;LC_MONETARY=Polish_Poland.1250;LC_NUMERIC=C;LC_TIME=Polish_Poland.1250
>
> attached base packages:
> [1] "stats"     "graphics"  "grDevices" "utils"     "datasets"  "methods"  
> [7] "base"     
>> 
>
>
>
>
> -b-e-g-i-n--r--c-o-d-e-
>
> setClass( "someclass", representation(v="numeric", l="character"),
>     prototype( v=numeric(0),
> 	l=character(0) )
>     )
>
> setMethod("initialize", "someclass",
> function(.Object, v=numeric(0), l=character(0))
> {
>     # strip the vector names
>     cv <- v
>     cl <- l
>     names(cv) <- NULL
>     names(cl) <- NULL
>     rval <- .Object
>     rval at v <- cv
>     rval at l <- cl
>     rval
> } )
>
> # at this point this should be OK
> o <- new("someclass", v=1:2, l=letters[1:3])
> o
>
> # check validity
> f <- function(object)
> {
>     rval <- NULL
>     if( length(object at v) != length(object at l) )
> 	rval <- c( rval, "lengths dont match")
>     if( is.null(rval) ) return(TRUE)
>     else return(rval)
> }
>  
> # this should return error description
> f(o)
>
>
> # define the validity method
> setValidity( "someclass", f)
>
> # this should return an error
> new("someclass", v=1:2, l=letters[1:3])
>
> # but it doesn't...
>
> -e-n-d--r--c-o-d-e-
>
>
>
>
> ____________________________________
> Michal Bojanowski
> ICS / Department of Sociology
> Utrecht University
> Heidelberglaan 2; 3584 CS Utrecht
> Room 1428
> m.j.bojanowski at uu dot nl
> http://www.fss.uu.nl/soc/bojanowski/
>
>
> 	[[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at stat.math.ethz.ch 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.

-- 
Martin Morgan
Bioconductor / Computational Biology
http://bioconductor.org



More information about the R-help mailing list