| 42333 |
ripley |
1 |
% File src/library/methods/man/NextMethod.Rd
|
|
|
2 |
% Part of the R package, http://www.R-project.org
|
| 59039 |
ripley |
3 |
% Copyright 1995-2011 R Core Team
|
| 42333 |
ripley |
4 |
% Distributed under GPL 2 or later
|
|
|
5 |
|
| 18558 |
jmc |
6 |
\name{callNextMethod}
|
| 56186 |
murdoch |
7 |
\alias{callNextMethod}
|
| 18558 |
jmc |
8 |
\title{Call an Inherited Method}
|
|
|
9 |
\description{
|
|
|
10 |
A call to \code{callNextMethod} can only appear inside a method
|
|
|
11 |
definition. It then results in a call to the first inherited method
|
|
|
12 |
after the current method, with the arguments to the current method
|
|
|
13 |
passed down to the next method. The value of that method call is the
|
|
|
14 |
value of \code{callNextMethod}.
|
|
|
15 |
}
|
|
|
16 |
\usage{
|
| 21345 |
jmc |
17 |
callNextMethod(...)
|
| 18558 |
jmc |
18 |
}
|
| 21345 |
jmc |
19 |
\arguments{
|
|
|
20 |
\item{\dots}{
|
| 38402 |
ripley |
21 |
Optionally, the arguments to the function in its next call
|
|
|
22 |
(but note that the dispatch is as in the detailed description below;
|
| 44506 |
maechler |
23 |
the arguments have no effect on selecting the next method.)
|
| 23838 |
jmc |
24 |
|
| 38402 |
ripley |
25 |
If no arguments are included in the call to \code{callNextMethod}, the
|
| 23898 |
jmc |
26 |
effect is to call the method with the current arguments.
|
|
|
27 |
See the detailed description for what this really means.
|
|
|
28 |
|
| 38402 |
ripley |
29 |
Calling with no arguments is often the natural way to use
|
| 23898 |
jmc |
30 |
\code{callNextMethod}; see the examples.
|
| 21345 |
jmc |
31 |
}
|
|
|
32 |
}
|
| 18558 |
jmc |
33 |
\details{
|
| 42963 |
ripley |
34 |
The \sQuote{next} method (i.e., the first inherited method) is defined
|
| 38402 |
ripley |
35 |
to be that method which \emph{would} have been called if the current
|
|
|
36 |
method did not exist. This is more-or-less literally what happens: The
|
|
|
37 |
current method (to be precise, the method with signature given by the
|
|
|
38 |
\code{defined} slot of the method from which \code{callNextMethod} is
|
|
|
39 |
called) is deleted from a copy of the methods for the current generic,
|
|
|
40 |
and \code{\link{selectMethod}} is called to find the next method (the
|
| 18558 |
jmc |
41 |
result is cached in a special object, so the search only typically
|
|
|
42 |
happens once per session per combination of argument classes).
|
| 44506 |
maechler |
43 |
|
| 38402 |
ripley |
44 |
Note that the preceding definition means that the next method is
|
|
|
45 |
defined uniquely when \code{setMethod} inserts the method containing
|
|
|
46 |
the \code{callNextMethod} call, given the definitions of the classes
|
|
|
47 |
in the signature. The choice does not depend on the path that gets us
|
|
|
48 |
to that method (for example, through inheritance or from another
|
|
|
49 |
\code{callNextMethod} call). This definition was not enforced in
|
|
|
50 |
versions of \R prior to 2.3.0, where the method was selected based on
|
|
|
51 |
the target signature, and so could vary depending on the actual
|
|
|
52 |
arguments.
|
| 18558 |
jmc |
53 |
|
|
|
54 |
It is also legal, and often useful, for the method called by
|
| 23898 |
jmc |
55 |
\code{callNextMethod} to itself have a call to
|
|
|
56 |
\code{callNextMethod}. This generally works as you would expect, but
|
|
|
57 |
for completeness be aware that it is possible to have ambiguous
|
|
|
58 |
inheritance in the S structure, in the sense that the same two
|
|
|
59 |
classes can appear as superclasses \emph{in the opposite order} in
|
|
|
60 |
two other class definitions. In this case the effect of a nested
|
|
|
61 |
instance of \code{callNextMethod} is not well defined. Such
|
|
|
62 |
inconsistent class hierarchies are both rare and nearly always the
|
|
|
63 |
result of bad design, but they are possible, and currently undetected.
|
| 18558 |
jmc |
64 |
|
|
|
65 |
The statement that the method is called with the current arguments is
|
|
|
66 |
more precisely as follows. Arguments that were missing in the current
|
|
|
67 |
call are still missing (remember that \code{"missing"} is a valid
|
|
|
68 |
class in a method signature). For a formal argument, say \code{x}, that
|
|
|
69 |
appears in the original call, there is a corresponding argument in the
|
| 42963 |
ripley |
70 |
next method call equivalent to \code{x = x}. In effect, this
|
| 18558 |
jmc |
71 |
means that the next method sees the same actual arguments, but
|
|
|
72 |
arguments are evaluated only once.
|
|
|
73 |
}
|
|
|
74 |
\value{
|
|
|
75 |
The value returned by the selected method.
|
|
|
76 |
}
|
|
|
77 |
\references{
|
| 46128 |
jmc |
78 |
Chambers, John M. (2008)
|
|
|
79 |
\emph{Software for Data Analysis: Programming with R}
|
|
|
80 |
Springer. (For the R version.)
|
| 18558 |
jmc |
81 |
|
| 46128 |
jmc |
82 |
Chambers, John M. (1998)
|
|
|
83 |
\emph{Programming with Data}
|
| 56211 |
maechler |
84 |
Springer (For the original S4 version.)
|
| 18558 |
jmc |
85 |
}
|
| 56211 |
maechler |
86 |
\seealso{\code{\link{callGeneric}} to call the generic function with the
|
|
|
87 |
current dispatch rules (typically for a group generic function);
|
|
|
88 |
\link{Methods} for the general behavior of method dispatch.
|
|
|
89 |
}
|
| 18558 |
jmc |
90 |
|
| 18976 |
jmc |
91 |
\examples{
|
| 18558 |
jmc |
92 |
|
|
|
93 |
## some class definitions with simple inheritance
|
| 19029 |
hornik |
94 |
setClass("B0" , representation(b0 = "numeric"))
|
| 18558 |
jmc |
95 |
|
| 24439 |
ripley |
96 |
setClass("B1", representation(b1 = "character"), contains = "B0")
|
| 18558 |
jmc |
97 |
|
| 24439 |
ripley |
98 |
setClass("B2", representation(b2 = "logical"), contains = "B1")
|
| 18558 |
jmc |
99 |
|
|
|
100 |
## and a rather silly function to illustrate callNextMethod
|
|
|
101 |
|
|
|
102 |
f <- function(x) class(x)
|
|
|
103 |
|
| 24439 |
ripley |
104 |
setMethod("f", "B0", function(x) c(x@b0^2, callNextMethod()))
|
|
|
105 |
setMethod("f", "B1", function(x) c(paste(x@b1,":"), callNextMethod()))
|
| 23898 |
jmc |
106 |
setMethod("f", "B2", function(x) c(x@b2, callNextMethod()))
|
| 18558 |
jmc |
107 |
|
| 24439 |
ripley |
108 |
b1 <- new("B1", b0 = 2, b1 = "Testing")
|
| 18558 |
jmc |
109 |
|
| 24439 |
ripley |
110 |
b2 <- new("B2", b2 = FALSE, b1 = "More testing", b0 = 10)
|
| 18558 |
jmc |
111 |
|
|
|
112 |
f(b2)
|
| 44506 |
maechler |
113 |
stopifnot(identical(f(b2), c(b2@b2, paste(b2@b1,":"), b2@b0^2, "B2")))
|
| 18558 |
jmc |
114 |
|
|
|
115 |
f(b1)
|
|
|
116 |
|
| 44506 |
maechler |
117 |
## a sneakier method: the *changed* x is used:
|
| 56211 |
maechler |
118 |
setMethod("f", "B2",
|
|
|
119 |
function(x) {x@b0 <- 111; c(x@b2, callNextMethod())})
|
| 44506 |
maechler |
120 |
f(b2)
|
|
|
121 |
stopifnot(identical(f(b2), c(b2@b2, paste(b2@b1,":"), 111^2, "B2")))
|
|
|
122 |
|
| 26000 |
ripley |
123 |
\dontshow{
|
| 24439 |
ripley |
124 |
## a version of the example with 1 more layer of nesting
|
| 23898 |
jmc |
125 |
|
| 24439 |
ripley |
126 |
## next methods calling next methods, with arguments; using group generics
|
| 23898 |
jmc |
127 |
setMethod("Ops", "B2",
|
|
|
128 |
function(e1, e2) callNextMethod())
|
| 38057 |
jmc |
129 |
setMethod("Ops", c("B0"),
|
| 23898 |
jmc |
130 |
function(e1, e2) callNextMethod(e1@b0, e2))
|
|
|
131 |
|
|
|
132 |
b2 + 1 # 11
|
|
|
133 |
|
|
|
134 |
b1 == 2 # TRUE
|
|
|
135 |
|
|
|
136 |
removeClass("B2"); removeClass("B1"); removeClass("B0")
|
|
|
137 |
|
|
|
138 |
removeGeneric("f")
|
|
|
139 |
|
|
|
140 |
removeMethods("Ops")
|
|
|
141 |
|
| 24563 |
ripley |
142 |
## tests of multiple callNextMethod
|
|
|
143 |
setClass("m1", representation(count = "numeric"), contains = "matrix",
|
|
|
144 |
prototype = prototype(count = 0))
|
|
|
145 |
mm1 <- new("m1", matrix(1:12, 3,4))
|
|
|
146 |
setMethod("[", "m1", function(x, i, j, ..., drop) callNextMethod())
|
|
|
147 |
|
|
|
148 |
setClass("m2", representation(sum = "numeric"), contains = "m1")
|
|
|
149 |
|
|
|
150 |
setMethod("Ops", c("m1", "m1"), function(e1, e2) {
|
|
|
151 |
as(e1, "matrix") <- callNextMethod()
|
|
|
152 |
e1@count <- max(e1@count, e2@count)+1
|
|
|
153 |
e1})
|
|
|
154 |
|
|
|
155 |
mm2 <- new("m2", matrix(1:12, 3, 4), sum = sum(1:12))
|
|
|
156 |
|
|
|
157 |
stopifnot(identical(mm2[,2], 4:6))
|
|
|
158 |
|
|
|
159 |
setClass("m3", representation(rowtags = "character"),contains = "m2")
|
|
|
160 |
|
| 56211 |
maechler |
161 |
setMethod("[", signature(x="m3", i = "character", j = "missing",
|
|
|
162 |
drop = "missing"),
|
| 24563 |
ripley |
163 |
function(x, i,j, ..., drop) {
|
|
|
164 |
xx <- callNextMethod(x, match(i, x@rowtags),)
|
|
|
165 |
x@.Data <- xx
|
|
|
166 |
x@rowtags <- x@rowtags[match(i, x@rowtags)]
|
|
|
167 |
x})
|
|
|
168 |
|
| 56211 |
maechler |
169 |
tm <- matrix(1:12, 4, 3)
|
| 24563 |
ripley |
170 |
|
| 56211 |
maechler |
171 |
mm3 <- new("m3", tm, rowtags = letters[1:4])
|
| 24563 |
ripley |
172 |
|
| 56211 |
maechler |
173 |
mmm <- mm3[c("b", "d")]
|
| 24563 |
ripley |
174 |
|
| 56211 |
maechler |
175 |
stopifnot(identical(mmm,
|
|
|
176 |
new("m3", tm[c(2, 4),], rowtags = c("b", "d"))))
|
| 24563 |
ripley |
177 |
|
|
|
178 |
removeClass("m3")
|
|
|
179 |
removeClass("m2")
|
|
|
180 |
removeClass("m1")
|
|
|
181 |
|
|
|
182 |
removeMethods("[")
|
| 18558 |
jmc |
183 |
}
|
| 23898 |
jmc |
184 |
|
|
|
185 |
}
|
| 18558 |
jmc |
186 |
\keyword{programming}
|
|
|
187 |
\keyword{classes}
|
|
|
188 |
\keyword{methods}
|