setMethod              package:methods              R Documentation

Create and Save a Method

Description:

     Create and save a formal method for a given function and list of
     classes.

Usage:

     setMethod(f, signature=character(), definition,
               where = topenv(parent.frame()),
               valueClass = NULL, sealed = FALSE)

     removeMethod(f, signature, where)

Arguments:

       f: A generic function or the character-string name of the
          function. 

signature: A match of formal argument names for 'f' with the
          character-string names of corresponding classes.  This
          argument can also just be the vector of class names, in which
          case the first name corresponds to the first formal argument,
          the next to the second formal argument, etc.

definition: A function definition, which will become the method called
          when the arguments in a call to 'f' match the classes in
          'signature', directly or through inheritance. 

   where: the database in which to store the definition of the method; 

          For 'removeMethod', the default is the location of the
          (first) instance of the method for this signature.

valueClass: If supplied, this argument asserts that the method will
          return a value of this class.  (At present this argument is
          stored but not explicitly used.) 

  sealed: If 'TRUE', the method so defined cannot be redefined by
          another call to 'setMethod' (although it can be removed and
          then re-assigned).  Note that this argument is an extension
          to the definition of 'setMethod' in the reference.

Details:

     R methods for a particular generic function are stored in an
     object of class 'MethodsList'.  The effect of calling 'setMethod'
     is to store 'definition'  in a 'MethodsList' object on database
     'where'.   If 'f' doesn't exist as a generic function, but there
     is an ordinary function of the same name and the same formal
     arguments, a new generic function is created, and the previous
     non-generic version of 'f' becomes the default method.  This is
     equivalent to the programmer calling 'setGeneric' for the same
     function; it's better practice to do the call explicitly, since it
     shows that you intend to turn 'f' into a generic function.

     Methods are stored in a hierarchical structure:  see Methods for
     how the objects are used to select a method, and 'MethodsList' for
     functions that manipulate the objects.

     The class names in the signature can be any formal class, plus
     predefined basic classes such as '"numeric"', '"character"', and
     '"matrix"'.  Two additional special class names can appear:
     '"ANY"', meaning that this argument can have any class at all; and
     '"missing"', meaning that this argument _must not_ appear in the
     call in order to match this signature.  Don't confuse these two: 
     if an argument isn't mentioned in a signature, it corresponds
     implicitly to class '"ANY"', not to '"missing"'.  See the example
     below.  Old-style ('S3') classes can also be used, if you need
     compatibility with these, but you should definitely declare these
     classes by calling 'setOldClass' if you want S3-style inheritance
     to work.

     While 'f' can correspond to methods defined on several packages or
     environments, the underlying model is that these together make up
     the definition for a single generic function.  When R proceeds to
     select and evaluate methods for 'f', the methods on the current
     search list are merged to form a single generic function and
     associated methods list.  When 'f' is called and a method is
     dispatched, the evaluator matches the classes of the actual
     arguments to the signatures of the available methods.  When a
     match is found, the body of the corresponding method is evaluated,
     but without rematching the arguments to 'f'.   Aside from not
     rematching the arguments, the computation proceeds as if the call
     had been to the method.  In particular, the lexical scope of the
     method is used.

     Method definitions can have default expressions for arguments.  If
     those arguments are then missing in the call to the generic
     function, the default expression in the method is used.  If the
     method definition has no default for the argument, then the
     expression (if any) supplied in the definition of the generic
     function itself is used.  But note that this expression will be
     evaluated in the environment defined by the method.

     It is possible to have some differences between the formal
     arguments to a method supplied to 'setMethod' and those of the
     generic. Roughly, if the generic has ... as one of its arguments,
     then the method may have extra formal arguments, which will be
     matched from the arguments matching ... in the call to 'f'.  (What
     actually happens is that a local function is created inside the
     method, with its formal arguments, and the method is re-defined to
     call that local function.)

     Method dispatch tries to match the class of the actual arguments
     in a call to the available methods collected for 'f'.  Roughly,
     for each formal argument in turn, we look for the best match (the
     exact same class or the nearest element in the value of 'extends'
     for that class) for which there is any possible method matching
     the remaining arguments.  See Methods for more details.

Value:

     These functions exist for their side-effect, in setting or
     removing a method in the object defining methods for the specified
     generic.

     The value returned by 'removeMethod' is 'TRUE' if a method was
     found to be removed.

References:

     The R package 'methods' implements, with a few exceptions, the
     programming interface for classes and methods in the book
     _Programming with Data_ (John M. Chambers, Springer, 1998), in
     particular sections 1.6, 2.7, 2.8, and chapters 7 and 8.

     While the programming interface for the 'methods' package follows
     the reference, the R software is an original implementation, so
     details in the reference that reflect the S4 implementation may
     appear differently in R.  Also, there are extensions to the
     programming interface developed more recently than the reference. 
     For a discussion of details and ongoing development, see
     '?Methods' and the pointers from that documentation..

See Also:

     method.skeleton, which is the recommended way to generate a
     skeleton of the call to 'setMethod', with the correct formal
     arguments and other details.

     Methods, 'MethodsList' for details of the implementation

Examples:

     require(graphics)
     ## methods for plotting track objects (see the example for setClass)
     ##
     ## First, with only one object as argument:
     setMethod("plot", signature(x="track", y="missing"),
       function(x,  y, ...) plot(slot(x, "x"), slot(x, "y"), ...)
     )
     ## Second, plot the data from the track on the y-axis against anything
     ## as the x data.
     setMethod("plot", signature(y = "track"),
      function(x, y, ...) plot(x, slot(y, "y"), ...)
     )
     ## and similarly with the track on the x-axis (using the short form of
     ## specification for signatures)
     setMethod("plot", "track",
      function(x, y, ...) plot(slot(x, "y"), y,  ...)
     )
     t1 <- new("track", x=1:20, y=(1:20)^2)
     tc1 <- new("trackCurve", t1)
     slot(tc1, "smooth") <- smooth.spline(slot(tc1, "x"), slot(tc1, "y"))$y #$
     plot(t1)
     plot(qnorm(ppoints(20)), t1)
     ## An example of inherited methods, and of conforming method arguments
     ## (note the dotCurve argument in the method, which will be pulled out
     ## of ... in the generic.
     setMethod("plot", c("trackCurve", "missing"),
     function(x, y, dotCurve = FALSE, ...) {
       plot(as(x, "track"))
       if(length(slot(x, "smooth") > 0))
         lines(slot(x, "x"), slot(x, "smooth"),
              lty = if(dotCurve) 2 else 1)
       }
     )
     ## the plot of tc1 alone has an added curve; other uses of tc1
     ## are treated as if it were a "track" object.
     plot(tc1, dotCurve = TRUE)
     plot(qnorm(ppoints(20)), tc1)

     ## defining methods for a special function.
     ## Although "[" and "length" are not ordinary functions
     ## methods can be defined for them.
     setMethod("[", "track",
       function(x, i, j, ..., drop) {
         x@x <- x@x[i]; x@y <- x@y[i]
         x
       })
     plot(t1[1:15])

     setMethod("length", "track", function(x)length(x@y))
     length(t1)

     ## methods can be defined for missing arguments as well
     setGeneric("summary") ## make the function into a generic

     ## A method for summary()
     ## The method definition can include the arguments, but
     ## if they're omitted, class "missing" is assumed.

     setMethod("summary", "missing", function() "<No Object>")

