Rev 44809 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/methods/man/GenericFunctions.Rd% Part of the R package, http://www.R-project.org% Copyright 1995-2007 R Core Development Team% Distributed under GPL 2 or later\name{GenericFunctions}\alias{GenericFunctions}\alias{isGeneric}\alias{isGroup}\alias{removeGeneric}% standardGeneric() is a .Primitive in 'base', not 'methods'%\alias{standardGeneric}\alias{getGenerics}\alias{allGenerics}\alias{dumpMethod}\alias{findFunction}\alias{dumpMethods}\alias{removeMethods}\alias{signature}\alias{setReplaceMethod}\alias{callGeneric}%% FIXME: These are basically not documented at all:%% ----- isGroup, setReplaceMethod, allGenerics\title{Tools for Managing Generic Functions}\description{The functions documented here manage collections of methods associatedwith a generic function, as well as providing information about thegeneric functions themselves.}\usage{isGeneric(f, where, fdef, getName = FALSE)isGroup(f, where, fdef)removeGeneric(f, where)%standardGeneric(f)dumpMethod(f, signature, file, where, def)findFunction(f, generic = TRUE, where = topenv(parent.frame()))dumpMethods(f, file, signature, methods, where)signature(\dots)removeMethods(f, where = topenv(parent.frame()), all = missing(where))setReplaceMethod(f, \dots, where = topenv(parent.frame()))getGenerics(where, searchForm = FALSE)allGenerics(where, searchForm = FALSE)callGeneric(\dots)}\section{Summary of Functions}{\describe{\item{\code{isGeneric}:}{Is there a function named \code{f}, and if so, is it a generic?The \code{getName} argument allows a function to find the namefrom a function definition. If it is \code{TRUE} then the name ofthe generic is returned, or \code{FALSE} if this is not a genericfunction definition.The behavior of \code{isGeneric} and \code{\link{getGeneric}} forprimitive functions is slightly different. These functions don'texist as formal function objects (for efficiency and historicalreasons), regardless of whether methods have been defined forthem. A call to \code{isGeneric} tells you whether methods havebeen defined for this primitive function, anywhere in the currentsearch list, or in the specified position \code{where}. Incontrast, a call to \code{\link{getGeneric}} will return what thegeneric for that function would be, even if no methods have beencurrently defined for it.}\item{\code{removeGeneric}, \code{removeMethods}:}{Remove all the methods for the generic function of thisname. In addition, \code{removeGeneric} removes the functionitself; \code{removeMethods} restores the non-generic functionwhich was the default method. If there was no default method,\code{removeMethods} leaves a generic function with no methods.}\item{\code{standardGeneric}:}{Dispatches a method from the current function call for the genericfunction \code{f}. It is an error to call\code{standardGeneric} anywhere except in the body of thecorresponding generic function.Note that \code{\link{standardGeneric}} is a primitive function inthe \pkg{base} packagefor efficiency % << MM: this is just my guess, what *are* the reasons?reasons, but rather documented here where it belongs naturally.}\item{\code{dumpMethod}:}{Dump the method for this generic function and signature.}\item{\code{findFunction}:}{return a list of either the positions on the search list, or thecurrent top-level environment, on which a function objectfor \code{name} exists. The returned value is \emph{always} alist, use the first element to access the first visible versionof the function. See the example.\emph{NOTE:} Use this rather than \code{\link{find}} with\code{mode="function"}, which is not as meaningful, and has a fewsubtle bugs from its use of regular expressions. Also,\code{findFunction} works correctly in the code for a packagewhen attaching the package via a call to \code{\link{library}}.}\item{\code{dumpMethods}:}{Dump all the methods for this generic.}\item{\code{signature}:}{Returns a named list of classes to be matched to arguments of ageneric function.}\item{\code{getGenerics}:}{ Returns the names of the genericfunctions that have methods defined on \code{where}; thisargument can be an environment or an index into the searchlist. By default, the whole search list is used.The methods definitions are stored withpackage qualifiers; for example, methods for function\code{"initialize"} might refer to two different functionsof that name, on different packages. The package namescorresponding to the method list object are contained in theslot \code{package} of the returned object. The form ofthe returned name can be plain (e.g., \code{"base"}), or inthe form used in the search list (\code{"package:base"})according to the value of \code{searchForm}}\item{\code{callGeneric}:}{In the body of a method, this function will make a call to thecurrent generic function. If no arguments are passed to\code{callGeneric}, the arguments to the current call are passeddown; otherwise, the arguments are interpreted as in a call to thegeneric function. If the generic is a primitive then argumentsmust be supplied.}}}\arguments{\item{f}{ The character string naming the function. }\item{where}{ The environment, namespace, or search-list positionfrom which to search for objects. By default, start at thetop-level environment of the calling function, typically the globalenvironment (i.e., use the search list), or the namespace of apackage from which the call came. It is important to supply thisargument when calling any of these functions indirectly. Withpackage namespaces, the default is likely to be wrong in such calls.}\item{signature}{ The class signature of the relevant method. Asignature is a named or unnamed vector of character strings. Ifnamed, the names must be formal argument names for the genericfunction. If \code{signature} is unnamed, the default is to usethe first \code{length(signature)} formal arguments of thefunction. }\item{file}{ The file or connection on which to dump method definitions. }\item{def}{ The function object defining the method; if omitted, thecurrent method definition corresponding to the signature. }\item{\dots}{Named or unnamed arguments to form a signature.}\item{generic}{In testing or finding functions, should genericfunctions be included. Supply as \code{FALSE} to get onlynon-generic functions.}\item{fdef}{Optional, the generic function definition.Usually omitted in calls to \code{isGeneric}}\item{getName}{If \code{TRUE}, \code{isGeneric} returns the name ofthe generic. By default, it returns \code{TRUE}. }\item{methods}{The methods object containing the methods to be dumped. By default,the methods defined for this generic (optionally on the specified\code{where} location).}\item{all}{in \code{removeMethods}, logical indicating if all(default) or only the first method found should be removed.}\item{searchForm}{In \code{getGenerics}, if \code{TRUE}, the\code{package} slot of the returned result is in the form usedby \code{search()}, otherwise as the simple package name (e.g,\code{"package:base"} vs \code{"base"}).}}\section{Details}{\describe{\item{\code{setGeneric}:}{If there is already a non-generic function of this name, it willbe used to define the generic unless \code{def} is supplied, andthe current function will become the default method for thegeneric.If \code{def} is supplied, this defines the generic function, andno default method will exist (often a good feature, if thefunction should only be available for a meaningful subset of allobjects).Arguments \code{group} and \code{valueClass} are retained forconsistency with S-Plus, but are currently not used.}\item{\code{isGeneric}:}{If the \code{fdef} argument is supplied, take this as thedefinition of the generic, and test whether it is really ageneric, with \code{f} as the name of the generic. (This argumentis not available in S-Plus.)}\item{\code{removeGeneric}:}{If \code{where} supplied, just remove the version on this elementof the search list; otherwise, removes the first versionencountered.}\item{\code{standardGeneric}:}{Generic functions should usually have a call to\code{standardGeneric} as their entire body. They can, however,do any other computations as well.The usual \code{setGeneric} (directly or through calling\code{setMethod}) creates a function with a call to\code{standardGeneric}.}\item{\code{dumpMethod}:}{The resulting source file will recreate the method.}\item{\code{findFunction}:}{If \code{generic} is \code{FALSE}, ignore generic functions.}\item{\code{dumpMethods}:}{If \code{signature} is supplied only the methods matching thisinitial signature are dumped. (This feature is not found inS-Plus: don't use it if you want compatibility.)}\item{\code{signature}:}{The advantage of using \code{signature} is to provide a check onwhich arguments you meant, as well as clearer documentation inyour method specification. In addition, \code{signature} checksthat each of the elements is a single character string.}\item{\code{removeMethods}:}{Returns \code{TRUE} if \code{f} was a generic function,\code{FALSE} (silently) otherwise.If there is a default method, the function will be re-assigned asa simple function with this definition.Otherwise, the generic function remains but with no methods (soany call to it will generate an error). In either case, afollowing call to \code{setMethod} will consistentlyre-establish the same generic function as before.}}}\references{The R package \pkg{methods} implements, with a few exceptions, theprogramming interface for classesand methods in the book \emph{Programming with Data} (JohnM. 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 inthe reference that reflect the S4 implementation may appeardifferently in R. Also, there are extensions to the programminginterface developed more recently than the reference. For adiscussion of details see \code{?\link{Methods}}and the links from that documentation.}\seealso{\code{\link{getMethod}} (also for \code{selectMethod}),\code{\link{setGeneric}},\code{\link{setClass}},\code{\link{showMethods}}}\examples{require(stats) # for lm## get the function "myFun" -- throw an error if 0 or > 1 versions visible:findFuncStrict <- function(fName) {allF <- findFunction(fName)if(length(allF) == 0)stop("No versions of ",fName," visible")else if(length(allF) > 1)stop(fName," is ambiguous: ", length(allF), " versions")elseget(fName, allF[[1]])}try(findFuncStrict("myFun"))# Error: no versionlm <- function(x) x+1try(findFuncStrict("lm"))# Error: 2 versionsfindFuncStrict("findFuncStrict")# just 1 versionrm(lm)\dontshow{## because nosegfault runs standardGeneric w/o the methods package, nothing## really gets tested. The following check that it catches some errorsmustDie <- function(expr) stopifnot(is(trySilent(expr), "try-error"))mustDie(standardGeneric()) # 3 tests of requiring a single stringmustDie(standardGeneric(NULL))mustDie(standardGeneric(""))mustDie(standardGeneric("notAGenericFunction"))mustDie(standardGeneric("show")) # a generic, but not called from its body}## method dumping ------------------------------------setClass("A", representation(a="numeric"))setMethod("plot", "A", function(x,y,...){ cat("A meth\n") })dumpMethod("plot","A", file="")\dontrun{setMethod("plot", "A",function (x, y, ...){cat("AAAAA\n")})}%donttmp <- tempfile()dumpMethod("plot","A", file=tmp)## now remove, and see if we can parse the dumpstopifnot(removeMethod("plot", "A"))source(tmp)stopifnot(is(getMethod("plot", "A"), "MethodDefinition"))## same with dumpMethods() :setClass("B", contains="A")setMethod("plot", "B", function(x,y,...){ cat("B ...\n") })dumpMethods("plot", file=tmp)stopifnot(removeMethod("plot", "A"),removeMethod("plot", "B"))source(tmp)stopifnot(is(getMethod("plot", "A"), "MethodDefinition"),is(getMethod("plot", "B"), "MethodDefinition"))}\keyword{programming}\keyword{classes}\keyword{methods}