| 42333 |
ripley |
1 |
% File src/library/methods/man/validObject.Rd
|
|
|
2 |
% Part of the R package, http://www.R-project.org
|
| 59039 |
ripley |
3 |
% Copyright 1995-2007 R Core Team
|
| 42333 |
ripley |
4 |
% Distributed under GPL 2 or later
|
|
|
5 |
|
| 16446 |
jmc |
6 |
\name{validObject}
|
| 56186 |
murdoch |
7 |
\alias{validObject}
|
| 44631 |
maechler |
8 |
\alias{getValidity}
|
| 16446 |
jmc |
9 |
\alias{setValidity}
|
|
|
10 |
\title{ Test the Validity of an Object }
|
|
|
11 |
\description{
|
|
|
12 |
The validity of \code{object} related to its class definition is
|
|
|
13 |
tested. If the object is valid, \code{TRUE} is returned; otherwise,
|
|
|
14 |
either a vector of strings describing validity failures is returned,
|
|
|
15 |
or an error is generated (according to whether \code{test} is
|
| 37545 |
jmc |
16 |
\code{TRUE}). Optionally, all slots in the object can also be validated.
|
| 16446 |
jmc |
17 |
|
| 33606 |
maechler |
18 |
The function \code{setValidity} sets the validity method of a class
|
|
|
19 |
(but more normally, this method will be supplied as the
|
|
|
20 |
\code{validity} argument to \code{\link{setClass}}). The method
|
|
|
21 |
should be a function of one object that returns \code{TRUE} or a
|
|
|
22 |
description of the non-validity.
|
| 16446 |
jmc |
23 |
}
|
|
|
24 |
\usage{
|
| 37545 |
jmc |
25 |
validObject(object, test = FALSE, complete = FALSE)
|
| 16446 |
jmc |
26 |
|
| 33606 |
maechler |
27 |
setValidity(Class, method, where = topenv(parent.frame()) )
|
| 44631 |
maechler |
28 |
|
|
|
29 |
getValidity(ClassDef)
|
| 16446 |
jmc |
30 |
}
|
|
|
31 |
\arguments{
|
| 39389 |
maechler |
32 |
\item{object}{ any object, but not much will happen unless the
|
| 16446 |
jmc |
33 |
object's class has a formal definition.}
|
| 39389 |
maechler |
34 |
\item{test}{logical; if \code{TRUE} and validity fails, the
|
| 16446 |
jmc |
35 |
function returns a vector of strings describing the problems. If
|
|
|
36 |
\code{test} is \code{FALSE} (the default) validity failure generates
|
|
|
37 |
an error.}
|
| 39389 |
maechler |
38 |
\item{complete}{logical; if \code{TRUE}, validity methods will be
|
|
|
39 |
applied recursively to any of the slots that have such methods.}
|
| 26530 |
maechler |
40 |
\item{Class}{the name or class definition of the class whose validity
|
|
|
41 |
method is to be set.}
|
| 44631 |
maechler |
42 |
\item{ClassDef}{a class definition object, as from
|
|
|
43 |
\code{\link{getClassDef}}.}
|
| 26530 |
maechler |
44 |
\item{method}{a validity method; that is, either \code{NULL} or a
|
| 41391 |
ripley |
45 |
function of one argument (\code{object}). Like
|
| 19029 |
hornik |
46 |
\code{validObject}, the function should return \code{TRUE} if the
|
|
|
47 |
object is valid, and one or more descriptive strings if any problems
|
|
|
48 |
are found. Unlike \code{validObject}, it should never generate an
|
|
|
49 |
error.
|
| 39389 |
maechler |
50 |
}
|
|
|
51 |
\item{where}{the modified class definition will be stored in this
|
|
|
52 |
environment.}
|
| 16446 |
jmc |
53 |
|
| 39389 |
maechler |
54 |
Note that validity methods do not have to check validity of
|
|
|
55 |
superclasses: the logic of \code{validObject} ensures these tests are
|
|
|
56 |
done once only. As a consequence, if one validity method wants to use
|
|
|
57 |
another, it should extract and call the method from the other
|
| 44631 |
maechler |
58 |
definition of the other class by calling \code{getValidity()}: it
|
| 39389 |
maechler |
59 |
should \emph{not} call \code{validObject}.
|
| 16446 |
jmc |
60 |
}
|
|
|
61 |
\details{
|
| 42963 |
ripley |
62 |
Validity testing takes place \sQuote{bottom up}: Optionally, if
|
| 39389 |
maechler |
63 |
\code{complete=TRUE}, the validity of the object's slots, if any, is
|
|
|
64 |
tested. Then, in all cases, for each of the classes that this class
|
| 42963 |
ripley |
65 |
extends (the \sQuote{superclasses}), the explicit validity method of
|
| 39389 |
maechler |
66 |
that class is called, if one exists. Finally, the validity method of
|
|
|
67 |
\code{object}'s class is called, if there is one.
|
| 16446 |
jmc |
68 |
|
|
|
69 |
Testing generally stops at the first stage of finding an error, except
|
|
|
70 |
that all the slots will be examined even if a slot has failed its
|
|
|
71 |
validity test.
|
| 37545 |
jmc |
72 |
|
|
|
73 |
The standard validity test (with \code{complete=FALSE}) is applied
|
|
|
74 |
when an object is created via \code{\link{new}} with any optional
|
|
|
75 |
arguments (without the extra arguments the result is just the class
|
|
|
76 |
prototype object).
|
| 41391 |
ripley |
77 |
|
|
|
78 |
An attempt is made to fix up the definition of a validity method if
|
|
|
79 |
its argument is not \code{object}.
|
| 16446 |
jmc |
80 |
}
|
|
|
81 |
\value{
|
| 19029 |
hornik |
82 |
\code{validObject} returns \code{TRUE} if the object is valid.
|
|
|
83 |
Otherwise a vector of strings describing problems found, except that
|
|
|
84 |
if \code{test} is \code{FALSE}, validity failure generates an error,
|
|
|
85 |
with the corresponding strings in the error message.
|
| 16446 |
jmc |
86 |
}
|
|
|
87 |
\references{
|
| 46128 |
jmc |
88 |
Chambers, John M. (2008)
|
|
|
89 |
\emph{Software for Data Analysis: Programming with R}
|
|
|
90 |
Springer. (For the R version.)
|
| 16446 |
jmc |
91 |
|
| 46128 |
jmc |
92 |
Chambers, John M. (1998)
|
|
|
93 |
\emph{Programming with Data}
|
| 61433 |
ripley |
94 |
Springer (For the original S4 version.)
|
| 16446 |
jmc |
95 |
}
|
| 44631 |
maechler |
96 |
\seealso{\code{\link{setClass}};
|
|
|
97 |
class \code{\linkS4class{classRepresentation}}.
|
|
|
98 |
}
|
| 16446 |
jmc |
99 |
\examples{
|
| 26000 |
ripley |
100 |
setClass("track",
|
|
|
101 |
representation(x="numeric", y = "numeric"))
|
| 41508 |
ripley |
102 |
t1 <- new("track", x=1:10, y=sort(stats::rnorm(10)))
|
| 26000 |
ripley |
103 |
## A valid "track" object has the same number of x, y values
|
| 41391 |
ripley |
104 |
validTrackObject <- function(object) {
|
|
|
105 |
if(length(object@x) == length(object@y)) TRUE
|
|
|
106 |
else paste("Unequal x,y lengths: ", length(object@x), ", ",
|
|
|
107 |
length(object@y), sep="")
|
| 16446 |
jmc |
108 |
}
|
| 26000 |
ripley |
109 |
## assign the function as the validity method for the class
|
|
|
110 |
setValidity("track", validTrackObject)
|
|
|
111 |
## t1 should be a valid "track" object
|
|
|
112 |
validObject(t1)
|
|
|
113 |
## Now we do something bad
|
| 37545 |
jmc |
114 |
t2 <- t1
|
|
|
115 |
t2@x <- 1:20
|
| 26000 |
ripley |
116 |
## This should generate an error
|
| 37545 |
jmc |
117 |
\dontrun{try(validObject(t2))}
|
|
|
118 |
\dontshow{stopifnot(is(try(validObject(t2)), "try-error"))}
|
|
|
119 |
|
|
|
120 |
setClass("trackCurve",
|
|
|
121 |
representation("track", smooth = "numeric"))
|
|
|
122 |
|
|
|
123 |
## all superclass validity methods are used when validObject
|
|
|
124 |
## is called from initialize() with arguments, so this fails
|
|
|
125 |
\dontrun{trynew("trackCurve", t2)}
|
|
|
126 |
\dontshow{stopifnot(is(try(new("trackCurve", t2)), "try-error"))}
|
|
|
127 |
|
|
|
128 |
setClass("twoTrack", representation(tr1 = "track", tr2 ="track"))
|
|
|
129 |
|
|
|
130 |
## validity tests are not applied recursively by default,
|
| 39389 |
maechler |
131 |
## so this object is created (invalidly)
|
| 37545 |
jmc |
132 |
tT <- new("twoTrack", tr2 = t2)
|
|
|
133 |
|
|
|
134 |
## A stricter test detects the problem
|
|
|
135 |
\dontrun{try(validObject(tT, complete = TRUE))}
|
|
|
136 |
\dontshow{stopifnot(is(try(validObject(tT, complete = TRUE)), "try-error"))}
|
| 26000 |
ripley |
137 |
}
|
| 17454 |
jmc |
138 |
\keyword{programming}
|
|
|
139 |
\keyword{classes}
|