Rev 40900 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
\name{validObject}\alias{validObject}\alias{setValidity}\title{ Test the Validity of an Object }\description{The validity of \code{object} related to its class definition istested. If the object is valid, \code{TRUE} is returned; otherwise,either a vector of strings describing validity failures is returned,or an error is generated (according to whether \code{test} is\code{TRUE}). Optionally, all slots in the object can also be validated.The function \code{setValidity} sets the validity method of a class(but more normally, this method will be supplied as the\code{validity} argument to \code{\link{setClass}}). The methodshould be a function of one object that returns \code{TRUE} or adescription of the non-validity.}\usage{validObject(object, test = FALSE, complete = FALSE)setValidity(Class, method, where = topenv(parent.frame()) )}\arguments{\item{object}{ any object, but not much will happen unless theobject's class has a formal definition.}\item{test}{logical; if \code{TRUE} and validity fails, thefunction returns a vector of strings describing the problems. If\code{test} is \code{FALSE} (the default) validity failure generatesan error.}\item{complete}{logical; if \code{TRUE}, validity methods will beapplied recursively to any of the slots that have such methods.}\item{Class}{the name or class definition of the class whose validitymethod is to be set.}\item{method}{a validity method; that is, either \code{NULL} or afunction of one argument (\code{object}). Like\code{validObject}, the function should return \code{TRUE} if theobject is valid, and one or more descriptive strings if any problemsare found. Unlike \code{validObject}, it should never generate anerror.}\item{where}{the modified class definition will be stored in thisenvironment.}Note that validity methods do not have to check validity ofsuperclasses: the logic of \code{validObject} ensures these tests aredone once only. As a consequence, if one validity method wants to useanother, it should extract and call the method from the otherdefinition of the other class by calling \code{\link{getValidity}}: itshould \emph{not} call \code{validObject}.}\details{Validity testing takes place \dQuote{bottom up}: Optionally, if\code{complete=TRUE}, the validity of the object's slots, if any, istested. Then, in all cases, for each of the classes that this classextends (the \dQuote{superclasses}), the explicit validity method ofthat class is called, if one exists. Finally, the validity method of\code{object}'s class is called, if there is one.Testing generally stops at the first stage of finding an error, exceptthat all the slots will be examined even if a slot has failed itsvalidity test.The standard validity test (with \code{complete=FALSE}) is appliedwhen an object is created via \code{\link{new}} with any optionalarguments (without the extra arguments the result is just the classprototype object).An attempt is made to fix up the definition of a validity method ifits argument is not \code{object}.}\value{\code{validObject} returns \code{TRUE} if the object is valid.Otherwise a vector of strings describing problems found, except thatif \code{test} is \code{FALSE}, validity failure generates an error,with the corresponding strings in the error message.}\references{The \R package \pkg{methods} implements, with a few exceptions, theprogramming interface for classes and methods in the book\emph{Programming with Data} (John M. Chambers, Springer, 1998), inparticular sections 1.6, 2.7, 2.8, and chapters 7 and 8.While the programming interface for the \pkg{methods} package followsthe reference, the R software is an original implementation, sodetails in the reference that reflect the S4 implementation may appeardifferently in R. Also, there are extensions to the programminginterface developed more recently than the reference. For adiscussion of details see \code{?\link{Methods}}and the links from that documentation.}\seealso{ \code{\link{setClass}}. }\examples{setClass("track",representation(x="numeric", y = "numeric"))t1 <- new("track", x=1:10, y=sort(rnorm(10)))## A valid "track" object has the same number of x, y valuesvalidTrackObject <- function(object) {if(length(object@x) == length(object@y)) TRUEelse paste("Unequal x,y lengths: ", length(object@x), ", ",length(object@y), sep="")}## assign the function as the validity method for the classsetValidity("track", validTrackObject)## t1 should be a valid "track" objectvalidObject(t1)## Now we do something badt2 <- t1t2@x <- 1:20## This should generate an error\dontrun{try(validObject(t2))}\dontshow{stopifnot(is(try(validObject(t2)), "try-error"))}setClass("trackCurve",representation("track", smooth = "numeric"))## all superclass validity methods are used when validObject## is called from initialize() with arguments, so this fails\dontrun{trynew("trackCurve", t2)}\dontshow{stopifnot(is(try(new("trackCurve", t2)), "try-error"))}setClass("twoTrack", representation(tr1 = "track", tr2 ="track"))## validity tests are not applied recursively by default,## so this object is created (invalidly)tT <- new("twoTrack", tr2 = t2)## A stricter test detects the problem\dontrun{try(validObject(tT, complete = TRUE))}\dontshow{stopifnot(is(try(validObject(tT, complete = TRUE)), "try-error"))}}\keyword{programming}\keyword{classes}