| 46314 |
jmc |
1 |
% File src/library/methods/man/dotsMethods.Rd
|
| 68948 |
ripley |
2 |
% Part of the R package, https://www.R-project.org
|
| 71228 |
maechler |
3 |
% Copyright 1995-2016 R Core Team
|
| 46314 |
jmc |
4 |
% Distributed under GPL 2 or later
|
|
|
5 |
|
|
|
6 |
\name{dotsMethods}
|
| 56186 |
murdoch |
7 |
\alias{dotsMethods}
|
| 54540 |
hornik |
8 |
\title{The Use of \code{...} in Method Signatures}
|
| 46314 |
jmc |
9 |
\description{
|
|
|
10 |
The \dQuote{\dots} argument in \R functions is treated specially, in that it
|
|
|
11 |
matches zero, one or more actual arguments (and so, objects). A
|
|
|
12 |
mechanism has been added to \R to allow \dQuote{\dots} as the signature of a
|
|
|
13 |
generic function. Methods defined for such functions will be
|
|
|
14 |
selected and called when \emph{all} the arguments matching \dQuote{\dots}
|
|
|
15 |
are from the specified class or from some subclass of that class.
|
|
|
16 |
}
|
|
|
17 |
|
|
|
18 |
\section{Using "..." in a Signature}{
|
|
|
19 |
Beginning with version 2.8.0 of \R, S4 methods can be dispatched
|
|
|
20 |
(selected and called) corresponding to the special argument \dQuote{\dots}.
|
|
|
21 |
Currently, \dQuote{\dots} cannot be mixed with other formal arguments:
|
|
|
22 |
either the signature of the generic function is \dQuote{\dots} only, or it
|
|
|
23 |
does not contain \dQuote{\dots}. (This restriction may be lifted in a future
|
|
|
24 |
version.)
|
|
|
25 |
|
|
|
26 |
Given a suitable generic function, methods are specified in the
|
|
|
27 |
usual way by a call to \code{\link{setMethod}}. The method
|
|
|
28 |
definition must be written expecting all the arguments corresponding
|
|
|
29 |
to \dQuote{\dots} to be from the class specified in the method's signature,
|
|
|
30 |
or from a class that extends that class (i.e., a subclass of that
|
|
|
31 |
class).
|
|
|
32 |
|
|
|
33 |
Typically the methods will pass \dQuote{\dots} down to another function or
|
|
|
34 |
will create a list of the arguments and iterate over that. See the
|
|
|
35 |
examples below.
|
|
|
36 |
|
|
|
37 |
When you have a computation that is suitable for more than one existing
|
|
|
38 |
class, a convenient approach may be to define a union of these
|
|
|
39 |
classes by a call to \code{\link{setClassUnion}}. See the example
|
|
|
40 |
below.
|
|
|
41 |
|
|
|
42 |
}
|
|
|
43 |
\section{Method Selection and Dispatch for "..."}{
|
| 71366 |
jmc |
44 |
See \link{Methods_Details} for a general discussion. The following assumes
|
| 46314 |
jmc |
45 |
you have read the \dQuote{Method Selection and Dispatch} section of
|
|
|
46 |
that documentation.
|
|
|
47 |
|
|
|
48 |
A method selecting on \dQuote{\dots} is specified by a single class in the
|
|
|
49 |
call to \code{\link{setMethod}}. If all the actual arguments
|
|
|
50 |
corresponding to \dQuote{\dots} have this class, the corresponding method is
|
|
|
51 |
selected directly.
|
|
|
52 |
|
|
|
53 |
Otherwise, the class of each argument and that class' superclasses are
|
|
|
54 |
computed, beginning with the first \dQuote{\dots} argument. For the first
|
|
|
55 |
argument, eligible methods are those for any of the classes. For
|
|
|
56 |
each succeeding argument that introduces a class not considered previously, the eligible methods are further
|
|
|
57 |
restricted to those matching the argument's class or
|
|
|
58 |
superclasses. If no further eligible classes exist, the iteration
|
|
|
59 |
breaks out and the default method, if any, is selected.
|
|
|
60 |
|
|
|
61 |
At the end of the iteration, one or more methods may be eligible.
|
|
|
62 |
If more than one, the selection looks for the method with the least
|
|
|
63 |
distance to the actual arguments. For each argument, any inherited
|
|
|
64 |
method corresponds to a distance, available from the \code{contains}
|
|
|
65 |
slot of the class definition. Since the same class can arise for
|
|
|
66 |
more than one argument, there may be several distances associated
|
|
|
67 |
with it. Combining them is inevitably arbitrary: the current
|
|
|
68 |
computation uses the minimum distance. Thus, for example, if a
|
|
|
69 |
method matched one argument directly, one as first generation
|
|
|
70 |
superclass and another as a second generation superclass, the
|
|
|
71 |
distances are 0, 1 and 2. The current selection computation would
|
|
|
72 |
use distance 0 for this
|
|
|
73 |
method. In particular, this selection criterion tends to use a method that
|
|
|
74 |
matches exactly one or more of the arguments' class.
|
|
|
75 |
|
|
|
76 |
As with ordinary method selection, there may be multiple methods
|
|
|
77 |
with the same distance. A warning message is issued and one of the
|
|
|
78 |
methods is chosen (the first encountered, which in this case is
|
|
|
79 |
rather arbitrary).
|
|
|
80 |
|
|
|
81 |
Notice that, while the computation examines all arguments, the
|
|
|
82 |
essential cost of dispatch goes up with the number of
|
|
|
83 |
\emph{distinct} classes among the arguments, likely to be much
|
|
|
84 |
smaller than the number of arguments when the latter is large.
|
|
|
85 |
|
|
|
86 |
}
|
|
|
87 |
|
|
|
88 |
\section{Implementation Details}{
|
|
|
89 |
Methods dispatching on \dQuote{\dots} were introduced in version 2.8.0 of
|
|
|
90 |
\R. The initial implementation of the corresponding selection and
|
|
|
91 |
dispatch is in an R function, for flexibility while the new
|
|
|
92 |
mechanism is being studied. In this implementation, a local version
|
| 72576 |
lawrence |
93 |
of \code{standardGeneric} is inserted in the generic function's
|
| 46314 |
jmc |
94 |
environment. The local version selects a method according to the
|
|
|
95 |
criteria above and calls that method, from the environment of the
|
|
|
96 |
generic function. This is slightly different from the action taken
|
|
|
97 |
by the C implementation when \dQuote{\dots} is not involved. Aside from the
|
|
|
98 |
extra computing time required, the method is evaluated in a true
|
|
|
99 |
function call, as opposed to the special context constructed by the
|
|
|
100 |
C version (which cannot be exactly replicated in R code.) However,
|
|
|
101 |
situations in which different computational results would
|
|
|
102 |
be obtained have not been encountered so far, and seem very
|
|
|
103 |
unlikely.
|
|
|
104 |
|
|
|
105 |
Methods dispatching on arguments other than \dQuote{\dots} are \emph{cached} by storing
|
|
|
106 |
the inherited method in the table of all methods, where it will be
|
|
|
107 |
found on the next selection with the same combination of classes
|
|
|
108 |
in the actual arguments (but not used for inheritance searches).
|
|
|
109 |
Methods based on \dQuote{\dots} are also cached, but not found quite
|
|
|
110 |
as immediately. As noted, the selected method depends only on the
|
|
|
111 |
set of classes that occur in the \dQuote{\dots} arguments. Each of
|
|
|
112 |
these classes can appear one or more times, so many combinations of
|
|
|
113 |
actual argument classes will give rise to the same effective
|
|
|
114 |
signature. The selection computation first computes and sorts the
|
|
|
115 |
distinct classes encountered. This gives a label that will be
|
|
|
116 |
cached in the table of all methods, avoiding any further search for
|
|
|
117 |
inherited classes after the first occurrence. A call to
|
|
|
118 |
\code{\link{showMethods}} will expose such inherited methods.
|
|
|
119 |
|
|
|
120 |
The intention is that the \dQuote{\dots} features will be added to the
|
|
|
121 |
standard C code when enough experience with them has been obtained.
|
|
|
122 |
It is possible that at the same time, combinations of \dQuote{\dots} with
|
|
|
123 |
other arguments in signatures may be supported.
|
|
|
124 |
}
|
|
|
125 |
|
|
|
126 |
\examples{
|
|
|
127 |
cc <- function(...)c(...)
|
|
|
128 |
|
|
|
129 |
setGeneric("cc")
|
|
|
130 |
|
|
|
131 |
setMethod("cc", "character", function(...)paste(...))
|
|
|
132 |
|
|
|
133 |
setClassUnion("Number", c("numeric", "complex"))
|
|
|
134 |
|
|
|
135 |
setMethod("cc", "Number", function(...) sum(...))
|
|
|
136 |
|
| 71228 |
maechler |
137 |
setClass("cdate", contains = "character", slots = c(date = "Date"))
|
| 46314 |
jmc |
138 |
|
| 71228 |
maechler |
139 |
setClass("vdate", contains = "vector", slots = c(date = "Date"))
|
| 46314 |
jmc |
140 |
|
| 47916 |
maechler |
141 |
cd1 <- new("cdate", "abcdef", date = Sys.Date())
|
| 46314 |
jmc |
142 |
|
| 47916 |
maechler |
143 |
cd2 <- new("vdate", "abcdef", date = Sys.Date())
|
| 46314 |
jmc |
144 |
|
| 56287 |
ripley |
145 |
stopifnot(identical(cc(letters, character(), cd1),
|
|
|
146 |
paste(letters, character(), cd1))) # the "character" method
|
| 46314 |
jmc |
147 |
|
| 56287 |
ripley |
148 |
stopifnot(identical(cc(letters, character(), cd2),
|
|
|
149 |
c(letters, character(), cd2)))
|
|
|
150 |
# the default, because "vdate" doesn't extend "character"
|
| 46314 |
jmc |
151 |
|
|
|
152 |
stopifnot(identical(cc(1:10, 1+1i), sum(1:10, 1+1i))) # the "Number" method
|
|
|
153 |
|
|
|
154 |
stopifnot(identical(cc(1:10, 1+1i, TRUE), c(1:10, 1+1i, TRUE))) # the default
|
|
|
155 |
|
|
|
156 |
stopifnot(identical(cc(), c())) # no arguments implies the default method
|
|
|
157 |
|
|
|
158 |
setGeneric("numMax", function(...)standardGeneric("numMax"))
|
|
|
159 |
|
| 56287 |
ripley |
160 |
setMethod("numMax", "numeric", function(...)max(...))
|
|
|
161 |
# won't work for complex data
|
|
|
162 |
setMethod("numMax", "Number", function(...) paste(...))
|
|
|
163 |
# should not be selected w/o complex args
|
| 46314 |
jmc |
164 |
|
|
|
165 |
stopifnot(identical(numMax(1:10, pi, 1+1i), paste(1:10, pi, 1+1i)))
|
|
|
166 |
stopifnot(identical(numMax(1:10, pi, 1), max(1:10, pi, 1)))
|
|
|
167 |
|
|
|
168 |
try(numMax(1:10, pi, TRUE)) # should be an error: no default method
|
|
|
169 |
|
|
|
170 |
## A generic version of paste(), dispatching on the "..." argument:
|
|
|
171 |
setGeneric("paste", signature = "...")
|
|
|
172 |
|
|
|
173 |
setMethod("paste", "Number", function(..., sep, collapse) c(...))
|
|
|
174 |
|
|
|
175 |
stopifnot(identical(paste(1:10, pi, 1), c(1:10, pi, 1)))
|
|
|
176 |
|
|
|
177 |
\dontshow{
|
|
|
178 |
for(gen in c("numMax", "cc", "paste")) removeGeneric(gen)
|
|
|
179 |
for(cl in c("Number", "vdate", "cdate")) removeClass(cl)
|
|
|
180 |
}
|
|
|
181 |
}
|
|
|
182 |
|
|
|
183 |
\references{
|
| 88585 |
hornik |
184 |
\bibshow{R:Chambers:2008}
|
|
|
185 |
(For the R version.)
|
| 46314 |
jmc |
186 |
|
| 88585 |
hornik |
187 |
\bibshow{R:Chambers:1998}
|
|
|
188 |
(For the original S4 version.)
|
| 46314 |
jmc |
189 |
}
|
|
|
190 |
\seealso{
|
| 71366 |
jmc |
191 |
For the general discussion of methods, see \link{Methods_Details} and links
|
| 46314 |
jmc |
192 |
from there.
|
|
|
193 |
}
|
|
|
194 |
\keyword{programming}
|
|
|
195 |
\keyword{classes}
|
|
|
196 |
\keyword{methods}
|