Rev 72576 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/methods/man/dotsMethods.Rd% Part of the R package, https://www.R-project.org% Copyright 1995-2016 R Core Team% Distributed under GPL 2 or later\name{dotsMethods}\alias{dotsMethods}\title{The Use of \code{...} in Method Signatures}\description{The \dQuote{\dots} argument in \R functions is treated specially, in that itmatches zero, one or more actual arguments (and so, objects). Amechanism has been added to \R to allow \dQuote{\dots} as the signature of ageneric function. Methods defined for such functions will beselected and called when \emph{all} the arguments matching \dQuote{\dots}are from the specified class or from some subclass of that class.}\section{Using "..." in a Signature}{Beginning with version 2.8.0 of \R, S4 methods can be dispatched(selected and called) corresponding to the special argument \dQuote{\dots}.Currently, \dQuote{\dots} cannot be mixed with other formal arguments:either the signature of the generic function is \dQuote{\dots} only, or itdoes not contain \dQuote{\dots}. (This restriction may be lifted in a futureversion.)Given a suitable generic function, methods are specified in theusual way by a call to \code{\link{setMethod}}. The methoddefinition must be written expecting all the arguments correspondingto \dQuote{\dots} to be from the class specified in the method's signature,or from a class that extends that class (i.e., a subclass of thatclass).Typically the methods will pass \dQuote{\dots} down to another function orwill create a list of the arguments and iterate over that. See theexamples below.When you have a computation that is suitable for more than one existingclass, a convenient approach may be to define a union of theseclasses by a call to \code{\link{setClassUnion}}. See the examplebelow.}\section{Method Selection and Dispatch for "..."}{See \link{Methods_Details} for a general discussion. The following assumesyou have read the \dQuote{Method Selection and Dispatch} section ofthat documentation.A method selecting on \dQuote{\dots} is specified by a single class in thecall to \code{\link{setMethod}}. If all the actual argumentscorresponding to \dQuote{\dots} have this class, the corresponding method isselected directly.Otherwise, the class of each argument and that class' superclasses arecomputed, beginning with the first \dQuote{\dots} argument. For the firstargument, eligible methods are those for any of the classes. Foreach succeeding argument that introduces a class not considered previously, the eligible methods are furtherrestricted to those matching the argument's class orsuperclasses. If no further eligible classes exist, the iterationbreaks out and the default method, if any, is selected.At the end of the iteration, one or more methods may be eligible.If more than one, the selection looks for the method with the leastdistance to the actual arguments. For each argument, any inheritedmethod corresponds to a distance, available from the \code{contains}slot of the class definition. Since the same class can arise formore than one argument, there may be several distances associatedwith it. Combining them is inevitably arbitrary: the currentcomputation uses the minimum distance. Thus, for example, if amethod matched one argument directly, one as first generationsuperclass and another as a second generation superclass, thedistances are 0, 1 and 2. The current selection computation woulduse distance 0 for thismethod. In particular, this selection criterion tends to use a method thatmatches exactly one or more of the arguments' class.As with ordinary method selection, there may be multiple methodswith the same distance. A warning message is issued and one of themethods is chosen (the first encountered, which in this case israther arbitrary).Notice that, while the computation examines all arguments, theessential cost of dispatch goes up with the number of\emph{distinct} classes among the arguments, likely to be muchsmaller than the number of arguments when the latter is large.}\section{Implementation Details}{Methods dispatching on \dQuote{\dots} were introduced in version 2.8.0 of\R. The initial implementation of the corresponding selection anddispatch is in an R function, for flexibility while the newmechanism is being studied. In this implementation, a local versionof \code{standardGeneric} is inserted in the generic function'senvironment. The local version selects a method according to thecriteria above and calls that method, from the environment of thegeneric function. This is slightly different from the action takenby the C implementation when \dQuote{\dots} is not involved. Aside from theextra computing time required, the method is evaluated in a truefunction call, as opposed to the special context constructed by theC version (which cannot be exactly replicated in R code.) However,situations in which different computational results wouldbe obtained have not been encountered so far, and seem veryunlikely.Methods dispatching on arguments other than \dQuote{\dots} are \emph{cached} by storingthe inherited method in the table of all methods, where it will befound on the next selection with the same combination of classesin the actual arguments (but not used for inheritance searches).Methods based on \dQuote{\dots} are also cached, but not found quiteas immediately. As noted, the selected method depends only on theset of classes that occur in the \dQuote{\dots} arguments. Each ofthese classes can appear one or more times, so many combinations ofactual argument classes will give rise to the same effectivesignature. The selection computation first computes and sorts thedistinct classes encountered. This gives a label that will becached in the table of all methods, avoiding any further search forinherited classes after the first occurrence. A call to\code{\link{showMethods}} will expose such inherited methods.The intention is that the \dQuote{\dots} features will be added to thestandard C code when enough experience with them has been obtained.It is possible that at the same time, combinations of \dQuote{\dots} withother arguments in signatures may be supported.}\examples{cc <- function(...)c(...)setGeneric("cc")setMethod("cc", "character", function(...)paste(...))setClassUnion("Number", c("numeric", "complex"))setMethod("cc", "Number", function(...) sum(...))setClass("cdate", contains = "character", slots = c(date = "Date"))setClass("vdate", contains = "vector", slots = c(date = "Date"))cd1 <- new("cdate", "abcdef", date = Sys.Date())cd2 <- new("vdate", "abcdef", date = Sys.Date())stopifnot(identical(cc(letters, character(), cd1),paste(letters, character(), cd1))) # the "character" methodstopifnot(identical(cc(letters, character(), cd2),c(letters, character(), cd2)))# the default, because "vdate" doesn't extend "character"stopifnot(identical(cc(1:10, 1+1i), sum(1:10, 1+1i))) # the "Number" methodstopifnot(identical(cc(1:10, 1+1i, TRUE), c(1:10, 1+1i, TRUE))) # the defaultstopifnot(identical(cc(), c())) # no arguments implies the default methodsetGeneric("numMax", function(...)standardGeneric("numMax"))setMethod("numMax", "numeric", function(...)max(...))# won't work for complex datasetMethod("numMax", "Number", function(...) paste(...))# should not be selected w/o complex argsstopifnot(identical(numMax(1:10, pi, 1+1i), paste(1:10, pi, 1+1i)))stopifnot(identical(numMax(1:10, pi, 1), max(1:10, pi, 1)))try(numMax(1:10, pi, TRUE)) # should be an error: no default method## A generic version of paste(), dispatching on the "..." argument:setGeneric("paste", signature = "...")setMethod("paste", "Number", function(..., sep, collapse) c(...))stopifnot(identical(paste(1:10, pi, 1), c(1:10, pi, 1)))\dontshow{for(gen in c("numMax", "cc", "paste")) removeGeneric(gen)for(cl in c("Number", "vdate", "cdate")) removeClass(cl)}}\references{Chambers, John M. (2008)\emph{Software for Data Analysis: Programming with R}Springer. (For the R version.)Chambers, John M. (1998)\emph{Programming with Data}Springer (For the original S4 version.)}\seealso{For the general discussion of methods, see \link{Methods_Details} and linksfrom there.}\keyword{programming}\keyword{classes}\keyword{methods}