I'm trying to figure out how NextMethod()
works. The most detailed explanation I have found of the S3 class system is in Chambers & Hastie (edts.)'s Statistical Models in S (1993, Chapman & Hall), however I find the part concerning NextMethod
invocation a little obscure. Following are the relevant paragraphs I'm trying to make sense of (pp. 268-269).
Turning now to methods invoked as a result of a call to
NextMethod()
, these behave as if they had been called from the previous method with a special call. The arguments in the call to the inherited method are the same in number, order, and actual argument names as those in the call to the current method (and, therefore, in the call to the generic). The expressions for the arguments, however, are the names of the corresponding formal arguments of the current method. Suppose, for example, that the expressionprint(ratings)
has invoked the methodprint.ordered()
. When this method invokesNextMethod()
, this is equivalent to a call toprint.factor()
of the formprint.factor(x)
, wherex
is here thex
in the frame ofprint.ordered()
. If several arguments match the formal argument "...
", those arguments are represented in the call to the inherited method y special names "..1
", "..2
", etc. The evaluator recognizes these names and treats them appropriately (see page 476 for an example).This rather subtle definition exists to ensure that the semantics of function calls in S carry over as cleanly as possible to the use of methods (compare Becker, Chambers and Wilks's The New S Language, page 354). In particular:
- Arguments are passed down from the current method to the inherited method with their current values at the time
NextMethod()
is called.- Lazy evaluation continues in effect; unevaluated arguments stay unevaluated.
- Missing arguments remain missing in the inherited method.
- Arguments passed through the "
...
" formal argument arrive with the correct argument name.- Objects in the frame that do not correspond to actual arguments in the call will not be passed to the inherited method."
The inheritance process is essentially transparent so far as the arguments go.
Two points that I find confusing are:
- What is "the current method" and what is "the previous method"?
- What is the difference between "The arguments in the call to the inherited method", "The expressions for the arguments" and "the names of the corresponding formal arguments of the current method"?
Generally speaking, if anyone could please restate the description given in the above paragraphs in a lucider fashion, I'd appreciate it.
Hard to go through all this post, but I think that this small example can help to demystify the
NextMethod
dispatching.I create an object with 2 classes attributes (inheritance) 'first' and 'second'.
Then I create a
generic
methodCat
to print my objectI define
Cate
method for each class.Now you can can check
Cate
call using this example:Cate.second(x = x, y = 1:3)