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
1 2 3
a character string naming a function (and not a
built-in operator). Required for
further arguments to be passed to the next method.
An R object is a data object which has a
attribute (and this can be tested by
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
"array" followed by the class of the underlying vector.
Most vectors have class the result of
that integer vectors have class
c("integer", "numeric") and
real vectors have class
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
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.
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
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.,
Namespaces can register methods for generic functions. To support
NextMethod search for methods in
two places: first in the environment in which the generic function
is called, and then 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.)
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
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
.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
NextMethod adds an attribute
.Class giving the
.Class last used for dispatch, and
.Class along to that used for dispatch.
.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.)
.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
would dispatch by manipulating
.Class, but ‘this is not
recommended unless you understand the inheritance mechanism
thoroughly’ (Chambers & Hastie, 1992, p. 469).
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.
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.
The draft ‘R Language Definition’.