UseMethod
Class Methods
Description
R possesses a simple generic function mechanism which can be used for an object-oriented style of programming. Method dispatch takes place based on the class(es) of the first argument to the generic function or of the object supplied as an argument to UseMethod
or NextMethod
.
Usage
UseMethod(generic, object) NextMethod(generic = NULL, object = NULL, ...)
Arguments
generic | a character string naming a function (and not a built-in operator). Required for |
object | for |
... | further arguments to be passed to the next method. |
Details
An R object is a data object which has a class
attribute (and this can be tested by is.object
). A class attribute is a character vector giving the names of the classes from which the object inherits. If the object does not have a class attribute, it has an implicit class. Matrices and arrays have class "matrix"
or"array"
followed by the class of the underlying vector. Most vectors have class the result of mode(x)
, except that integer vectors have class c("integer", "numeric")
and real vectors have class c("double", "numeric")
.
When a function calling UseMethod("fun")
is applied to an object with class attribute c("first", "second")
, the system searches for a function called fun.first
and, if it finds it, applies it to the object. If no such function is found a function called fun.second
is tried. If no class name produces a suitable function, the function fun.default
is used, if it exists, or an error results.
Function methods
can be used to find out about the methods for a particular generic function or class.
UseMethod
is a primitive function but uses standard argument matching. It is not the only means of dispatch of methods, for there are internal generic and group generic functions. UseMethod
currently dispatches on the implicit class even for arguments that are not objects, but the other means of dispatch do not.
NextMethod
invokes the next method (determined by the class vector, either of the object supplied to the generic, or of the first argument to the function containing NextMethod
if a method was invoked directly). Normally NextMethod
is used with only one argument, generic
, but if further arguments are supplied these modify the call to the next method.
NextMethod
should not be called except in methods called by UseMethod
or from internal generics (see InternalGenerics). In particular it will not work inside anonymous calling functions (e.g., get("print.ts")(AirPassengers)
).
Namespaces can register methods for generic functions. To support this, UseMethod
and NextMethod
search for methods in two places: in the environment in which the generic function is called, and in the registration data base for the environment in which the generic is defined (typically a namespace). So methods for a generic function need to be available in the environment of the call to the generic, or they must be registered. (It does not matter whether they are visible in the environment in which the generic is defined.) As from R 3.5.0, the registration data base is searched after the top level environment (see topenv
) of the calling environment (but before the parents of the top level environment).
Technical Details
Now for some obscure details that need to appear somewhere. These comments will be slightly different than those in Chambers(1992). (See also the draft ‘R Language Definition’.) UseMethod
creates a new function call with arguments matched as they came in to the generic. Any local variables defined before the call to UseMethod
are retained (unlike S). Any statements after the call to UseMethod
will not be evaluated as UseMethod
does not return. UseMethod
can be called with more than two arguments: a warning will be given and additional arguments ignored. (They are not completely ignored in S.) If it is called with just one argument, the class of the first argument of the enclosing function is used as object
: unlike S this is the first actual argument passed and not the current value of the object of that name.
NextMethod
works by creating a special call frame for the next method. If no new arguments are supplied, the arguments will be the same in number, order and name as those to the current method but their values will be promises to evaluate their name in the current method and environment. Any named arguments matched to ...
are handled specially: they either replace existing arguments of the same name or are appended to the argument list. They are passed on as the promise that was supplied as an argument to the current environment. (S does this differently!) If they have been evaluated in the current (or a previous environment) they remain evaluated. (This is a complex area, and subject to change: see the draft ‘R Language Definition’.)
The search for methods for NextMethod
is slightly different from that for UseMethod
. Finding no fun.default
is not necessarily an error, as the search continues to the generic itself. This is to pick up an internal generic like [
which has no separate default method, and succeeds only if the generic is a primitive function or a wrapper for a .Internal
function of the same name. (When a primitive is called as the default method, argument matching may not work as described above due to the different semantics of primitives.)
You will see objects such as .Generic
, .Method
, and .Class
used in methods. These are set in the environment within which the method is evaluated by the dispatch mechanism, which is as follows:
-
Find the context for the calling function (the generic): this gives us the unevaluated arguments for the original call.
-
Evaluate the object (usually an argument) to be used for dispatch, and find a method (possibly the default method) or throw an error.
-
Create an environment for evaluating the method and insert special variables (see below) into that environment. Also copy any variables in the environment of the generic that are not formal (or actual) arguments.
-
Fix up the argument list to be the arguments of the call matched to the formals of the method.
.Generic
is a length-one character vector naming the generic function.
.Method
is a character vector (normally of length one) naming the method function. (For functions in the group generic Ops
it is of length two.)
.Class
is a character vector of classes used to find the next method. NextMethod
adds an attribute "previous"
to .Class
giving the .Class
last used for dispatch, and shifts .Class
along to that used for dispatch.
.GenericCallEnv
and .GenericDefEnv
are the environments of the call to be generic and defining the generic respectively. (The latter is used to find methods registered for the generic.)
Note that .Class
is set when the generic is called, and is unchanged if the class of the dispatching argument is changed in a method. It is possible to change the method that NextMethod
would dispatch by manipulating .Class
, but ‘this is not recommended unless you understand the inheritance mechanism thoroughly’ (Chambers & Hastie, 1992, p. 469).
Note
This scheme is called S3 (S version 3). For new projects, it is recommended to use the more flexible and robust S4 scheme provided in the methods package.
References
Chambers, J. M. (1992) Classes and methods: object-oriented programming in S. Appendix A of Statistical Models in S eds J. M. Chambers and T. J. Hastie, Wadsworth & Brooks/Cole.
See Also
The draft ‘R Language Definition’.
methods
, class
, getS3method
, is.object
.
Copyright (©) 1999–2012 R Foundation for Statistical Computing.
Licensed under the GNU General Public License.