The R Project SVN R

Rev

Rev 88267 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
42333 ripley 1
% File src/library/methods/man/NextMethod.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
 
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
71937 jmc 41
  result is cached in the method object where the call occurred, so the search typically
42
  happens only once per session per combination of argument classes).
44506 maechler 43
 
71937 jmc 44
  The next method is defined from the \emph{signature} of the current
45
  method, not from the actual classes of the arguments.
46
  In particular, modifying any of the arguments has no effect on the
47
  selection.
48
  As a result, the selected next method can be called with invalid
49
  arguments if the calling function assigns objects of a different
50
  class before the \code{callNextMethod()} call.
51
  Be careful of any assignments to such arguments.
18558 jmc 52
 
71937 jmc 53
  It is possible for the selection of the next method to be ambiguous,
54
  even though the original set of methods was consistent.
55
  See the section \dQuote{Ambiguous Selection}.
18558 jmc 56
 
57
  The statement that the method is called with the current arguments is
58
  more precisely as follows.  Arguments that were missing in the current
59
  call are still missing (remember that \code{"missing"} is a valid
60
  class in a method signature).  For a formal argument, say \code{x}, that
61
  appears in the original call, there is a corresponding argument in the
42963 ripley 62
  next method call equivalent to \code{x = x}.  In effect, this
18558 jmc 63
  means that the next method sees the same actual arguments, but
64
  arguments are evaluated only once.
65
}
71937 jmc 66
\section{Ambiguous Selection}{
67
There are two fairly common situations in which the choice of a next
68
method is ambiguous, even when the original set of methods uniquely
69
defines all method selection unambiguously.
70
In these situations, \code{callNextMethod()} should be replaced,
71
either by a call to a specific function or by recalling the generic
72
with different arguments.
73
 
74
The most likely situation arises with methods for binary operators,
75
typically through one of the group generic functions.
76
See the example for class \code{"rnum"} below.
77
Examples of this sort usually require three methods: two for the case
78
that the first or the second argument comes from the class, and a
79
third for the case that both arguments come from the class.
80
If that last method uses \code{callNextMethod}, the other two methods
81
are equally valid.  The ambiguity is exactly the same that required
82
defining the two-argument method in the first place.
83
 
84
In fact, the two possibilities are equally valid conceptually as well
85
as formally.
86
As in the example below, the logic of the application usually requires
87
selecting a computation explicitly or else calling the generic
88
function with modified arguments to select an appropriate method.
89
 
90
The other likely source of ambiguity arises from a class that inherits
91
directly from more than one other class (a \dQuote{mixin} in standard
92
terminology).
93
If the generic has methods corresponding to both superclasses, a
94
method for the current class is again needed to resolve ambiguity.
95
Using \code{callNextMethod} will again reimpose the ambiguity.
96
Again, some explicit choice has to be made in the calling method
97
instead.
98
 
99
These ambiguities are not the result of bad design, but they do
100
require workarounds.
101
Other ambiguities usually reflect inconsistencies in the tree of
102
inheritances, such as a class appearing in more than one place among
103
the superclasses.
104
Such cases should be rare, but with the independent definition of
105
classes in multiple packages, they can't be ruled out.
106
 
107
}
18558 jmc 108
\value{
109
  The value returned by the selected method.
110
}
111
\references{
88585 hornik 112
   \bibshow{R:Chambers:2016}
113
  (Chapters 9 and 10.)
18558 jmc 114
}
56211 maechler 115
\seealso{\code{\link{callGeneric}} to call the generic function with the
116
 current dispatch rules (typically for a group generic function);
71366 jmc 117
 \link{Methods_Details} for the general behavior of method dispatch.
56211 maechler 118
}
18558 jmc 119
 
18976 jmc 120
\examples{
71937 jmc 121
## callNextMethod() used for the Math, Math2 group generic functions
18558 jmc 122
 
71937 jmc 123
## A class to automatically round numeric results to "d" digits
18558 jmc 124
 
71937 jmc 125
rnum <- setClass("rnum", slots = c(d = "integer"), contains = "numeric")
18558 jmc 126
 
71937 jmc 127
## Math functions operate on the rounded numbers, return a plain
128
## vector.  The next method will always be the default, usually a primitive.
129
setMethod("Math", "rnum",
130
          function(x)
131
              callNextMethod(round(as.numeric(x), x@d)))
132
setMethod("Math2", "rnum",
133
          function(x, digits)
134
              callNextMethod(round(as.numeric(x), x@d), digits))
18558 jmc 135
 
71937 jmc 136
## Examples of callNextMethod with two arguments in the signature.
18558 jmc 137
 
71937 jmc 138
## For arithmetic and one rnum with anything, callNextMethod with no arguments
139
## round the full accuracy result, and return as plain vector
140
setMethod("Arith", c(e1 ="rnum"),
141
          function(e1, e2)
142
              as.numeric(round(callNextMethod(), e1@d)))
143
setMethod("Arith", c(e2 ="rnum"),
144
          function(e1, e2)
145
              as.numeric(round(callNextMethod(), e2@d)))
18558 jmc 146
 
71937 jmc 147
## A method for BOTH arguments from "rnum" would be ambiguous
148
## for callNextMethod(): the two methods above are equally valid.
149
## The method chooses the smaller number of digits,
150
## and then calls the generic function, postponing the method selection
151
## until it's not ambiguous.
152
setMethod("Arith", c(e1 ="rnum", e2 = "rnum"),
153
          function(e1, e2) {
154
              if(e1@d <= e2@d)
155
                  callGeneric(e1, as.numeric(e2))
156
              else
157
                  callGeneric(as.numeric(e1), e2)
158
          })
18558 jmc 159
 
71937 jmc 160
## For comparisons, callNextMethod with the rounded arguments
161
setMethod("Compare", c(e1 = "rnum"),
162
          function(e1, e2)
163
              callNextMethod(round(e1, e1@d), round(e2, e1@d)))
164
setMethod("Compare", c(e2 = "rnum"),
165
          function(e1, e2)
166
              callNextMethod(round(e1, e2@d), round(e2, e2@d)))
18558 jmc 167
 
71937 jmc 168
## similarly to the Arith case, the method for two "rnum" objects
169
## can not unambiguously use callNextMethod().  Instead, we rely on
88267 maechler 170
## The rnum() method inherited from Math2 to return plain vectors.
71937 jmc 171
setMethod("Compare", c(e1 ="rnum", e2 = "rnum"),
172
          function(e1, e2) {
173
              d <- min(e1@d, e2@d)
174
              callGeneric(round(e1, d), round(e2, d))
175
          })
176
 
177
 
178
 
179
 
180
set.seed(867)
181
 
182
x1 <- rnum(10*runif(5), d=1L)
183
x2 <- rnum(10*runif(5), d=2L)
184
 
185
x1+1
186
x2*2
187
x1-x2
188
 
189
## Simple examples to illustrate callNextMethod with and without arguments
190
B0 <- setClass("B0", slots = c(s0 = "numeric"))
191
 
192
## and a function to illustrate callNextMethod
193
 
194
f <- function(x, text = "default") {
195
    str(x) # print a summary
196
    paste(text, ":", class(x))
197
}
198
 
199
setGeneric("f")
200
setMethod("f", "B0", function(x, text = "B0") {
201
    cat("B0 method called with s0 =", x@s0, "\n")
202
    callNextMethod()
203
})
204
 
205
b0 <- B0(s0 = 1)
206
 
207
## call f() with 2 arguments: callNextMethod passes both to the default method
208
f(b0, "first test")
209
 
210
## call f() with 1 argument:  the default "B0" is not passed by callNextMethod
211
f(b0)
212
 
213
## Now, a class that extends B0, with no methods for f()
214
B1 <- setClass("B1", slots = c(s1 = "character"), contains = "B0")
215
b1 <- B1(s0 = 2, s1 = "Testing B1")
216
 
217
## the two cases work as before, by inheriting the "B0" method
218
 
219
f(b1, b1@s1)
220
 
18558 jmc 221
f(b1)
222
 
71937 jmc 223
B2 <- setClass("B2", contains = "B1")
224
 
225
## And, a method for "B2" that calls with explicit arguments.
226
## Note that the method selection in callNextMethod
227
## uses the class of the *argument* to consistently select the "B0" method
228
 
229
setMethod("f", "B2", function(x, text = "B1 method") {
230
    y <- B1(s0 = -x@s0, s1 ="Modified x")
231
    callNextMethod(y, text)
232
})
233
 
234
b2 <- B2(s1 = "Testing B2", s0 = 10)
235
 
236
f(b2, b2@s1)
237
 
44506 maechler 238
f(b2)
239
 
23898 jmc 240
 
71937 jmc 241
## Be careful:  the argument passed must be legal for the method selected
242
## Although the argument here is numeric, it's still the "B0" method that's called
243
setMethod("f", "B2", function(x, text = "B1 method") {
244
    callNextMethod(x@s0, text)
245
})
23898 jmc 246
 
71937 jmc 247
##  Now the call will cause an error:
23898 jmc 248
 
71937 jmc 249
tryCatch(f(b2), error = function(e) cat(e$message,"\n"))
23898 jmc 250
 
71937 jmc 251
 
252
\dontshow{
253
##$
23898 jmc 254
removeClass("B2"); removeClass("B1"); removeClass("B0")
255
 
256
removeGeneric("f")
257
 
71937 jmc 258
removeMethods(all=FALSE,"Arith"); removeMethods(all=FALSE,"Compare")
259
removeMethods(all=FALSE,"Math"); removeMethods(all=FALSE,"Math2")
23898 jmc 260
 
24563 ripley 261
## tests of multiple callNextMethod
71228 maechler 262
setClass("m1", slots = c(count = "numeric"), contains = "matrix",
24563 ripley 263
         prototype = prototype(count = 0))
264
mm1 <- new("m1", matrix(1:12, 3,4))
265
setMethod("[", "m1", function(x, i, j, ..., drop) callNextMethod())
266
 
71228 maechler 267
setClass("m2", slots = c(sum = "numeric"), contains = "m1")
24563 ripley 268
 
269
setMethod("Ops", c("m1", "m1"), function(e1, e2) {
270
    as(e1, "matrix") <- callNextMethod()
271
    e1@count <- max(e1@count, e2@count)+1
272
    e1})
273
 
274
mm2 <- new("m2", matrix(1:12, 3, 4), sum = sum(1:12))
275
 
276
stopifnot(identical(mm2[,2], 4:6))
277
 
71228 maechler 278
setClass("m3", slots = c(rowtags = "character"),contains = "m2")
24563 ripley 279
 
56211 maechler 280
setMethod("[", signature(x="m3", i = "character", j = "missing",
281
                         drop = "missing"),
24563 ripley 282
          function(x, i,j, ..., drop) {
283
              xx <- callNextMethod(x, match(i, x@rowtags),)
284
              x@.Data <- xx
285
              x@rowtags <- x@rowtags[match(i, x@rowtags)]
286
              x})
287
 
56211 maechler 288
tm <- matrix(1:12, 4, 3)
24563 ripley 289
 
56211 maechler 290
mm3 <- new("m3", tm, rowtags = letters[1:4])
24563 ripley 291
 
56211 maechler 292
mmm <- mm3[c("b", "d")]
24563 ripley 293
 
56211 maechler 294
stopifnot(identical(mmm,
295
      new("m3", tm[c(2, 4),], rowtags = c("b", "d"))))
24563 ripley 296
 
297
removeClass("m3")
298
removeClass("m2")
299
removeClass("m1")
300
 
71937 jmc 301
removeMethods(all=FALSE,"[")
302
removeMethods(all=FALSE,"Ops")
18558 jmc 303
}
23898 jmc 304
 
305
}
18558 jmc 306
\keyword{programming}
307
\keyword{classes}
308
\keyword{methods}