| 42333 |
ripley |
1 |
% File src/library/methods/man/validObject.Rd
|
| 68948 |
ripley |
2 |
% Part of the R package, https://www.R-project.org
|
| 71956 |
ripley |
3 |
% Copyright 1995-2017 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{
|
| 71909 |
jmc |
12 |
\code{validObject()} tests the validity of \code{object} related to
|
|
|
13 |
its class definition; specifically, it checks that all slots
|
|
|
14 |
specified in the class definition are present and that the object in
|
|
|
15 |
the slot is from the required class or a subclass of that class.
|
| 16446 |
jmc |
16 |
|
| 71909 |
jmc |
17 |
If the object is valid, \code{TRUE} is returned; otherwise, an error
|
|
|
18 |
is generated, reporting all the validity failures encountered.
|
|
|
19 |
If argument \code{test} is
|
|
|
20 |
\code{TRUE}, the errors are returned as a character vector rather
|
|
|
21 |
than generating an error.
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
When an object from a class is initialized, the default method for
|
|
|
25 |
\code{\link{initialize}()} calls \code{validObject}.
|
|
|
26 |
|
|
|
27 |
A class definition may have a validity method, set by a call to
|
|
|
28 |
the function \code{setValidity}, in the package or environment that
|
|
|
29 |
defines the class (or via the \code{validity} argument to \code{\link{setClass}}). The method
|
|
|
30 |
should be a function of one object that returns \code{TRUE} or a character-string
|
| 33606 |
maechler |
31 |
description of the non-validity.
|
| 71909 |
jmc |
32 |
If such a method exists, it will be called from \code{validObject}
|
|
|
33 |
and any strings from failure will be included in the result or the
|
|
|
34 |
error message.
|
|
|
35 |
Any validity methods defined for superclasses (from the \code{contains=}
|
| 74363 |
maechler |
36 |
argument to \code{\link{setClass}}), will also be called.
|
| 71909 |
jmc |
37 |
|
|
|
38 |
|
| 16446 |
jmc |
39 |
}
|
|
|
40 |
\usage{
|
| 37545 |
jmc |
41 |
validObject(object, test = FALSE, complete = FALSE)
|
| 16446 |
jmc |
42 |
|
| 33606 |
maechler |
43 |
setValidity(Class, method, where = topenv(parent.frame()) )
|
| 44631 |
maechler |
44 |
|
|
|
45 |
getValidity(ClassDef)
|
| 16446 |
jmc |
46 |
}
|
|
|
47 |
\arguments{
|
| 39389 |
maechler |
48 |
\item{object}{ any object, but not much will happen unless the
|
| 16446 |
jmc |
49 |
object's class has a formal definition.}
|
| 39389 |
maechler |
50 |
\item{test}{logical; if \code{TRUE} and validity fails, the
|
| 16446 |
jmc |
51 |
function returns a vector of strings describing the problems. If
|
|
|
52 |
\code{test} is \code{FALSE} (the default) validity failure generates
|
|
|
53 |
an error.}
|
| 71909 |
jmc |
54 |
\item{complete}{logical; if \code{TRUE}, \code{validObject} is
|
|
|
55 |
called recursively for each of the slots. The default is \code{FALSE}.}
|
| 26530 |
maechler |
56 |
\item{Class}{the name or class definition of the class whose validity
|
|
|
57 |
method is to be set.}
|
| 44631 |
maechler |
58 |
\item{ClassDef}{a class definition object, as from
|
|
|
59 |
\code{\link{getClassDef}}.}
|
| 26530 |
maechler |
60 |
\item{method}{a validity method; that is, either \code{NULL} or a
|
| 41391 |
ripley |
61 |
function of one argument (\code{object}). Like
|
| 19029 |
hornik |
62 |
\code{validObject}, the function should return \code{TRUE} if the
|
|
|
63 |
object is valid, and one or more descriptive strings if any problems
|
|
|
64 |
are found. Unlike \code{validObject}, it should never generate an
|
|
|
65 |
error.
|
| 39389 |
maechler |
66 |
}
|
| 71909 |
jmc |
67 |
\item{where}{an environment to store the modified class
|
|
|
68 |
definition. Should be omitted, specifically for calls from a package that defines the class.
|
|
|
69 |
The definition will be stored in the
|
|
|
70 |
namespace of the package.}
|
| 16446 |
jmc |
71 |
|
|
|
72 |
}
|
| 71909 |
jmc |
73 |
\section{Validity methods}{
|
|
|
74 |
A validity method must be a function of one argument; formally, that
|
|
|
75 |
argument should be named \code{object}.
|
|
|
76 |
If the argument has a different name, \code{setValidity} makes the
|
|
|
77 |
substitution but in obscure cases that might fail, so it's wiser to
|
|
|
78 |
name the
|
|
|
79 |
argument \code{object}.
|
|
|
80 |
|
|
|
81 |
A good method checks all the possible errors and returns a character
|
|
|
82 |
vector citing all the exceptions found, rather than returning after
|
|
|
83 |
the first one.
|
|
|
84 |
\code{validObject} will accumulate these errors in its error message
|
|
|
85 |
or its return value.
|
|
|
86 |
|
|
|
87 |
Note that validity methods do not have to check validity of
|
|
|
88 |
superclasses: \code{validObject} calls such methods explicitly.
|
|
|
89 |
}
|
| 16446 |
jmc |
90 |
\details{
|
| 71909 |
jmc |
91 |
Validity testing takes place \sQuote{bottom up}, checking the slots,
|
|
|
92 |
then the superclasses, then the object's own validity method, if
|
|
|
93 |
there is one.
|
|
|
94 |
|
|
|
95 |
For each slot and superclass, the existence of the specified class is
|
|
|
96 |
checked.
|
|
|
97 |
For each slot, the object in the slot is tested for inheritance from
|
|
|
98 |
the corresponding class.
|
| 81927 |
smeyer |
99 |
If \code{complete} is \code{TRUE}, \code{validObject} is called
|
| 71909 |
jmc |
100 |
recursively for the object in the slot.
|
|
|
101 |
|
|
|
102 |
Then, for each of the classes that this class
|
| 42963 |
ripley |
103 |
extends (the \sQuote{superclasses}), the explicit validity method of
|
| 39389 |
maechler |
104 |
that class is called, if one exists. Finally, the validity method of
|
|
|
105 |
\code{object}'s class is called, if there is one.
|
| 16446 |
jmc |
106 |
|
|
|
107 |
}
|
|
|
108 |
\value{
|
| 19029 |
hornik |
109 |
\code{validObject} returns \code{TRUE} if the object is valid.
|
|
|
110 |
Otherwise a vector of strings describing problems found, except that
|
|
|
111 |
if \code{test} is \code{FALSE}, validity failure generates an error,
|
|
|
112 |
with the corresponding strings in the error message.
|
| 16446 |
jmc |
113 |
}
|
|
|
114 |
\references{
|
| 88585 |
hornik |
115 |
\bibshow{R:Chambers:2016}
|
|
|
116 |
(Chapters 9 and 10.)
|
| 16446 |
jmc |
117 |
}
|
| 44631 |
maechler |
118 |
\seealso{\code{\link{setClass}};
|
|
|
119 |
class \code{\linkS4class{classRepresentation}}.
|
|
|
120 |
}
|
| 16446 |
jmc |
121 |
\examples{
|
| 26000 |
ripley |
122 |
setClass("track",
|
| 71228 |
maechler |
123 |
slots = c(x="numeric", y = "numeric"))
|
| 41508 |
ripley |
124 |
t1 <- new("track", x=1:10, y=sort(stats::rnorm(10)))
|
| 26000 |
ripley |
125 |
## A valid "track" object has the same number of x, y values
|
| 41391 |
ripley |
126 |
validTrackObject <- function(object) {
|
|
|
127 |
if(length(object@x) == length(object@y)) TRUE
|
|
|
128 |
else paste("Unequal x,y lengths: ", length(object@x), ", ",
|
|
|
129 |
length(object@y), sep="")
|
| 16446 |
jmc |
130 |
}
|
| 26000 |
ripley |
131 |
## assign the function as the validity method for the class
|
|
|
132 |
setValidity("track", validTrackObject)
|
|
|
133 |
## t1 should be a valid "track" object
|
|
|
134 |
validObject(t1)
|
|
|
135 |
## Now we do something bad
|
| 37545 |
jmc |
136 |
t2 <- t1
|
|
|
137 |
t2@x <- 1:20
|
| 26000 |
ripley |
138 |
## This should generate an error
|
| 37545 |
jmc |
139 |
\dontrun{try(validObject(t2))}
|
|
|
140 |
\dontshow{stopifnot(is(try(validObject(t2)), "try-error"))}
|
|
|
141 |
|
| 71228 |
maechler |
142 |
setClass("trackCurve", contains = "track",
|
| 71229 |
maechler |
143 |
slots = c(smooth = "numeric"))
|
| 37545 |
jmc |
144 |
|
|
|
145 |
## all superclass validity methods are used when validObject
|
|
|
146 |
## is called from initialize() with arguments, so this fails
|
|
|
147 |
\dontrun{trynew("trackCurve", t2)}
|
|
|
148 |
\dontshow{stopifnot(is(try(new("trackCurve", t2)), "try-error"))}
|
|
|
149 |
|
| 71228 |
maechler |
150 |
setClass("twoTrack", slots = c(tr1 = "track", tr2 ="track"))
|
| 37545 |
jmc |
151 |
|
|
|
152 |
## validity tests are not applied recursively by default,
|
| 39389 |
maechler |
153 |
## so this object is created (invalidly)
|
| 37545 |
jmc |
154 |
tT <- new("twoTrack", tr2 = t2)
|
|
|
155 |
|
|
|
156 |
## A stricter test detects the problem
|
|
|
157 |
\dontrun{try(validObject(tT, complete = TRUE))}
|
|
|
158 |
\dontshow{stopifnot(is(try(validObject(tT, complete = TRUE)), "try-error"))}
|
| 26000 |
ripley |
159 |
}
|
| 17454 |
jmc |
160 |
\keyword{programming}
|
|
|
161 |
\keyword{classes}
|