Rev 81927 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/methods/man/validObject.Rd% Part of the R package, https://www.R-project.org% Copyright 1995-2017 R Core Team% Distributed under GPL 2 or later\name{validObject}\alias{validObject}\alias{getValidity}\alias{setValidity}\title{ Test the Validity of an Object }\description{\code{validObject()} tests the validity of \code{object} related toits class definition; specifically, it checks that all slotsspecified in the class definition are present and that the object inthe slot is from the required class or a subclass of that class.If the object is valid, \code{TRUE} is returned; otherwise, an erroris generated, reporting all the validity failures encountered.If argument \code{test} is\code{TRUE}, the errors are returned as a character vector ratherthan generating an error.When an object from a class is initialized, the default method for\code{\link{initialize}()} calls \code{validObject}.A class definition may have a validity method, set by a call tothe function \code{setValidity}, in the package or environment thatdefines the class (or via the \code{validity} argument to \code{\link{setClass}}). The methodshould be a function of one object that returns \code{TRUE} or a character-stringdescription of the non-validity.If such a method exists, it will be called from \code{validObject}and any strings from failure will be included in the result or theerror message.Any validity methods defined for superclasses (from the \code{contains=}argument to \code{\link{setClass}}), will also be called.}\usage{validObject(object, test = FALSE, complete = FALSE)setValidity(Class, method, where = topenv(parent.frame()) )getValidity(ClassDef)}\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}, \code{validObject} iscalled recursively for each of the slots. The default is \code{FALSE}.}\item{Class}{the name or class definition of the class whose validitymethod is to be set.}\item{ClassDef}{a class definition object, as from\code{\link{getClassDef}}.}\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}{an environment to store the modified classdefinition. Should be omitted, specifically for calls from a package that defines the class.The definition will be stored in thenamespace of the package.}}\section{Validity methods}{A validity method must be a function of one argument; formally, thatargument should be named \code{object}.If the argument has a different name, \code{setValidity} makes thesubstitution but in obscure cases that might fail, so it's wiser toname theargument \code{object}.A good method checks all the possible errors and returns a charactervector citing all the exceptions found, rather than returning afterthe first one.\code{validObject} will accumulate these errors in its error messageor its return value.Note that validity methods do not have to check validity ofsuperclasses: \code{validObject} calls such methods explicitly.}\details{Validity testing takes place \sQuote{bottom up}, checking the slots,then the superclasses, then the object's own validity method, ifthere is one.For each slot and superclass, the existence of the specified class ischecked.For each slot, the object in the slot is tested for inheritance fromthe corresponding class.If \code{complete} is \code{TRUE}, \code{validObject} is calledrecursively for the object in the slot.Then, for each of the classes that this classextends (the \sQuote{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.}\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{\bibshow{R:Chambers:2016}(Chapters 9 and 10.)}\seealso{\code{\link{setClass}};class \code{\linkS4class{classRepresentation}}.}\examples{setClass("track",slots = c(x="numeric", y = "numeric"))t1 <- new("track", x=1:10, y=sort(stats::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", contains = "track",slots = c(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", slots = c(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}