| 42333 |
ripley |
1 |
% File src/library/methods/man/setClassUnion.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 |
|
| 25351 |
jmc |
6 |
\name{setClassUnion}
|
| 56186 |
murdoch |
7 |
\alias{setClassUnion}
|
| 25351 |
jmc |
8 |
\alias{isClassUnion}
|
|
|
9 |
\alias{ClassUnionRepresentation-class}
|
|
|
10 |
\title{Classes Defined as the Union of Other Classes}
|
|
|
11 |
\description{
|
|
|
12 |
A class may be defined as the \emph{union} of other classes; that
|
|
|
13 |
is, as a virtual class defined as a superclass of several other
|
|
|
14 |
classes. Class unions are useful in method signatures or as slots in
|
|
|
15 |
other classes, when we want to allow one of several classes to be supplied.
|
|
|
16 |
}
|
|
|
17 |
\usage{
|
|
|
18 |
setClassUnion(name, members, where)
|
|
|
19 |
isClassUnion(Class)
|
|
|
20 |
}
|
|
|
21 |
\arguments{
|
|
|
22 |
\item{name}{ the name for the new union class. }
|
|
|
23 |
\item{members}{ the classes that should be members of this union.}
|
|
|
24 |
\item{where}{ where to save the new class definition; by default,
|
|
|
25 |
the environment of the package in which the \code{setClassUnion}
|
|
|
26 |
call appears, or the global environment if called outside of the
|
|
|
27 |
source of a package.}
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
\item{Class}{ the name or definition of a class.
|
|
|
31 |
}
|
|
|
32 |
}
|
|
|
33 |
\details{
|
|
|
34 |
The classes in \code{members} must be defined before creating the
|
|
|
35 |
union. However, members can be added later on to an existing
|
|
|
36 |
union, as shown in the example below. Class unions can be
|
|
|
37 |
members of other class unions.
|
|
|
38 |
|
| 58548 |
jmc |
39 |
The prototype object in the class union definition will be
|
|
|
40 |
\code{NULL} if class \code{"NULL"} is a member of the union and
|
|
|
41 |
the prototype object of the first member class otherwise (as of
|
|
|
42 |
version 2.15.0 of R; earlier versions had a \code{NULL} prototype even if
|
|
|
43 |
that was not valid).
|
|
|
44 |
|
| 25351 |
jmc |
45 |
Class unions are the only way to create a class that is extended by
|
|
|
46 |
a class whose definition is sealed (for example, the
|
|
|
47 |
basic datatypes or other classes defined in the base or methods
|
|
|
48 |
package in R are sealed). You cannot say \code{setIs("function", "other")}
|
|
|
49 |
unless \code{"other"} is a class union. In general, a
|
|
|
50 |
\code{setIs} call of this form changes the definition of the
|
|
|
51 |
first class mentioned (adding \code{"other"} to the list of
|
|
|
52 |
superclasses contained in the definition of \code{"function"}).
|
|
|
53 |
|
|
|
54 |
Class unions get around this by not modifying the first class
|
|
|
55 |
definition, relying instead on storing information in the subclasses
|
|
|
56 |
slot of the class union. In order for this technique to work, the
|
|
|
57 |
internal computations for expressions such as
|
|
|
58 |
\code{\link{extends}(class1, class2)} work
|
|
|
59 |
differently for class unions than for regular classes; specifically,
|
|
|
60 |
they test whether any class is in common between the superclasses of
|
|
|
61 |
\code{class1} and the subclasses of \code{class2}.
|
|
|
62 |
|
|
|
63 |
The different behavior for class unions is made possible because the
|
|
|
64 |
class definition object for class unions has itself a special class,
|
| 44751 |
maechler |
65 |
\code{"ClassUnionRepresentation"}, an extension of class
|
|
|
66 |
\code{\linkS4class{classRepresentation}}.
|
| 25351 |
jmc |
67 |
}
|
|
|
68 |
|
|
|
69 |
\references{
|
| 46128 |
jmc |
70 |
Chambers, John M. (2008)
|
|
|
71 |
\emph{Software for Data Analysis: Programming with R}
|
|
|
72 |
Springer. (For the R version.)
|
| 25351 |
jmc |
73 |
|
| 46128 |
jmc |
74 |
Chambers, John M. (1998)
|
|
|
75 |
\emph{Programming with Data}
|
|
|
76 |
Springer (For the original S4 version.)
|
| 25351 |
jmc |
77 |
}
|
|
|
78 |
|
|
|
79 |
\examples{
|
|
|
80 |
## a class for either numeric or logical data
|
|
|
81 |
setClassUnion("maybeNumber", c("numeric", "logical"))
|
|
|
82 |
|
|
|
83 |
## use the union as the data part of another class
|
|
|
84 |
setClass("withId", representation("maybeNumber", id = "character"))
|
|
|
85 |
|
|
|
86 |
w1 <- new("withId", 1:10, id = "test 1")
|
|
|
87 |
w2 <- new("withId", sqrt(w1)\%\%1 < .01, id = "Perfect squares")
|
|
|
88 |
|
|
|
89 |
## add class "complex" to the union "maybeNumber"
|
|
|
90 |
setIs("complex", "maybeNumber")
|
|
|
91 |
|
|
|
92 |
w3 <- new("withId", complex(real = 1:10, imaginary = sqrt(1:10)))
|
|
|
93 |
|
|
|
94 |
## a class union containing the existing class union "OptionalFunction"
|
|
|
95 |
setClassUnion("maybeCode",
|
|
|
96 |
c("expression", "language", "OptionalFunction"))
|
|
|
97 |
|
|
|
98 |
is(quote(sqrt(1:10)), "maybeCode") ## TRUE
|
| 26000 |
ripley |
99 |
\dontshow{
|
| 25351 |
jmc |
100 |
## The following test is less trivial than it looks.
|
|
|
101 |
## It depends on the assignment of the data part NOT performing a
|
|
|
102 |
## strict coerce to "numeric" on the way to satisfying
|
|
|
103 |
## is(ttt, "maybeNumber").
|
|
|
104 |
stopifnot(identical(w1@.Data, 1:10))
|
| 57838 |
jmc |
105 |
removeClass("withId")
|
|
|
106 |
removeClass("maybeNumber")
|
| 25351 |
jmc |
107 |
}
|
|
|
108 |
|
|
|
109 |
}
|
|
|
110 |
\keyword{programming}
|
|
|
111 |
\keyword{classes}
|