| 42333 |
ripley |
1 |
% File src/library/methods/man/GenericFunctions.Rd
|
| 68948 |
ripley |
2 |
% Part of the R package, https://www.R-project.org
|
| 71228 |
maechler |
3 |
% Copyright 1995-2016 R Core Team
|
| 42333 |
ripley |
4 |
% Distributed under GPL 2 or later
|
|
|
5 |
|
| 17000 |
jmc |
6 |
\name{GenericFunctions}
|
| 56186 |
murdoch |
7 |
\alias{GenericFunctions}
|
| 17000 |
jmc |
8 |
\alias{isGeneric}
|
|
|
9 |
\alias{isGroup}
|
|
|
10 |
\alias{removeGeneric}
|
|
|
11 |
\alias{getGenerics}
|
|
|
12 |
\alias{dumpMethod}
|
|
|
13 |
\alias{findFunction}
|
|
|
14 |
\alias{dumpMethods}
|
|
|
15 |
\alias{removeMethods}
|
|
|
16 |
\alias{signature}
|
|
|
17 |
\alias{setReplaceMethod}
|
| 33634 |
maechler |
18 |
%% FIXME: These are basically not documented at all:
|
| 45630 |
maechler |
19 |
%% ----- isGroup, setReplaceMethod
|
| 17000 |
jmc |
20 |
\title{Tools for Managing Generic Functions}
|
| 19029 |
hornik |
21 |
\description{
|
|
|
22 |
The functions documented here manage collections of methods associated
|
|
|
23 |
with a generic function, as well as providing information about the
|
|
|
24 |
generic functions themselves.
|
|
|
25 |
}
|
| 17000 |
jmc |
26 |
\usage{
|
|
|
27 |
isGeneric(f, where, fdef, getName = FALSE)
|
|
|
28 |
isGroup(f, where, fdef)
|
|
|
29 |
removeGeneric(f, where)
|
|
|
30 |
|
|
|
31 |
dumpMethod(f, signature, file, where, def)
|
| 33635 |
maechler |
32 |
findFunction(f, generic = TRUE, where = topenv(parent.frame()))
|
| 17000 |
jmc |
33 |
dumpMethods(f, file, signature, methods, where)
|
| 17262 |
hornik |
34 |
signature(\dots)
|
| 17000 |
jmc |
35 |
|
| 56311 |
ripley |
36 |
removeMethods(f, where = topenv(parent.frame()), all = missing(where))
|
| 56287 |
ripley |
37 |
|
| 33635 |
maechler |
38 |
setReplaceMethod(f, \dots, where = topenv(parent.frame()))
|
| 17000 |
jmc |
39 |
|
| 20092 |
jmc |
40 |
getGenerics(where, searchForm = FALSE)
|
| 17000 |
jmc |
41 |
}
|
| 17211 |
jmc |
42 |
\section{Summary of Functions}{
|
| 19029 |
hornik |
43 |
\describe{
|
| 31891 |
maechler |
44 |
\item{\code{isGeneric}:}{
|
| 19029 |
hornik |
45 |
Is there a function named \code{f}, and if so, is it a generic?
|
| 17211 |
jmc |
46 |
|
| 19029 |
hornik |
47 |
The \code{getName} argument allows a function to find the name
|
|
|
48 |
from a function definition. If it is \code{TRUE} then the name of
|
|
|
49 |
the generic is returned, or \code{FALSE} if this is not a generic
|
|
|
50 |
function definition.
|
| 17000 |
jmc |
51 |
|
| 19029 |
hornik |
52 |
The behavior of \code{isGeneric} and \code{\link{getGeneric}} for
|
|
|
53 |
primitive functions is slightly different. These functions don't
|
|
|
54 |
exist as formal function objects (for efficiency and historical
|
|
|
55 |
reasons), regardless of whether methods have been defined for
|
|
|
56 |
them. A call to \code{isGeneric} tells you whether methods have
|
| 33635 |
maechler |
57 |
been defined for this primitive function, anywhere in the current
|
|
|
58 |
search list, or in the specified position \code{where}. In
|
|
|
59 |
contrast, a call to \code{\link{getGeneric}} will return what the
|
|
|
60 |
generic for that function would be, even if no methods have been
|
|
|
61 |
currently defined for it.
|
| 19029 |
hornik |
62 |
}
|
| 31891 |
maechler |
63 |
|
|
|
64 |
\item{\code{removeGeneric}, \code{removeMethods}:}{
|
|
|
65 |
Remove all the methods for the generic function of this
|
| 20676 |
jmc |
66 |
name. In addition, \code{removeGeneric} removes the function
|
|
|
67 |
itself; \code{removeMethods} restores the non-generic function
|
|
|
68 |
which was the default method. If there was no default method,
|
|
|
69 |
\code{removeMethods} leaves a generic function with no methods.
|
| 19029 |
hornik |
70 |
}
|
| 31891 |
maechler |
71 |
\item{\code{standardGeneric}:}{
|
| 19029 |
hornik |
72 |
Dispatches a method from the current function call for the generic
|
| 22294 |
jmc |
73 |
function \code{f}. It is an error to call
|
|
|
74 |
\code{standardGeneric} anywhere except in the body of the
|
|
|
75 |
corresponding generic function.
|
| 33659 |
maechler |
76 |
|
|
|
77 |
Note that \code{\link{standardGeneric}} is a primitive function in
|
|
|
78 |
the \pkg{base} package
|
|
|
79 |
for efficiency % << MM: this is just my guess, what *are* the reasons?
|
|
|
80 |
reasons, but rather documented here where it belongs naturally.
|
| 19029 |
hornik |
81 |
}
|
| 31891 |
maechler |
82 |
\item{\code{dumpMethod}:}{
|
|
|
83 |
Dump the method for this generic function and signature.
|
| 19029 |
hornik |
84 |
}
|
| 31891 |
maechler |
85 |
\item{\code{findFunction}:}{
|
| 25351 |
jmc |
86 |
return a list of either the positions on the search list, or the
|
|
|
87 |
current top-level environment, on which a function object
|
|
|
88 |
for \code{name} exists. The returned value is \emph{always} a
|
|
|
89 |
list, use the first element to access the first visible version
|
|
|
90 |
of the function. See the example.
|
| 17000 |
jmc |
91 |
|
| 19029 |
hornik |
92 |
\emph{NOTE:} Use this rather than \code{\link{find}} with
|
|
|
93 |
\code{mode="function"}, which is not as meaningful, and has a few
|
| 25351 |
jmc |
94 |
subtle bugs from its use of regular expressions. Also,
|
|
|
95 |
\code{findFunction} works correctly in the code for a package
|
|
|
96 |
when attaching the package via a call to \code{\link{library}}.
|
| 19029 |
hornik |
97 |
}
|
| 31891 |
maechler |
98 |
\item{\code{dumpMethods}:}{
|
|
|
99 |
Dump all the methods for this generic.
|
| 19029 |
hornik |
100 |
}
|
| 31891 |
maechler |
101 |
\item{\code{signature}:}{
|
| 19029 |
hornik |
102 |
Returns a named list of classes to be matched to arguments of a
|
|
|
103 |
generic function.
|
|
|
104 |
}
|
| 45630 |
maechler |
105 |
\item{\code{getGenerics}:}{returns the names of the generic
|
| 33634 |
maechler |
106 |
functions that have methods defined on \code{where}; this
|
|
|
107 |
argument can be an environment or an index into the search
|
|
|
108 |
list. By default, the whole search list is used.
|
| 20092 |
jmc |
109 |
|
| 33634 |
maechler |
110 |
The methods definitions are stored with
|
|
|
111 |
package qualifiers; for example, methods for function
|
|
|
112 |
\code{"initialize"} might refer to two different functions
|
|
|
113 |
of that name, on different packages. The package names
|
|
|
114 |
corresponding to the method list object are contained in the
|
|
|
115 |
slot \code{package} of the returned object. The form of
|
|
|
116 |
the returned name can be plain (e.g., \code{"base"}), or in
|
|
|
117 |
the form used in the search list (\code{"package:base"})
|
|
|
118 |
according to the value of \code{searchForm}}
|
| 45824 |
jmc |
119 |
|
| 17000 |
jmc |
120 |
}
|
|
|
121 |
}
|
|
|
122 |
|
|
|
123 |
\arguments{
|
|
|
124 |
\item{f}{ The character string naming the function. }
|
| 56382 |
murdoch |
125 |
\item{where}{ The environment, namespace, or search-list position
|
| 26093 |
jmc |
126 |
from which to search for objects. By default, start at the
|
|
|
127 |
top-level environment of the calling function, typically the global
|
| 56382 |
murdoch |
128 |
environment (i.e., use the search list), or the namespace of a
|
| 26093 |
jmc |
129 |
package from which the call came. It is important to supply this
|
|
|
130 |
argument when calling any of these functions indirectly. With
|
| 56382 |
murdoch |
131 |
package namespaces, the default is likely to be wrong in such calls.}
|
| 17000 |
jmc |
132 |
|
|
|
133 |
\item{signature}{ The class signature of the relevant method. A
|
|
|
134 |
signature is a named or unnamed vector of character strings. If
|
|
|
135 |
named, the names must be formal argument names for the generic
|
| 51304 |
jmc |
136 |
function. Signatures are matched to the arguments specified in
|
|
|
137 |
the signature slot of the generic function (see the Details
|
| 61433 |
ripley |
138 |
section of the \code{\link{setMethod}} documentation).
|
| 31891 |
maechler |
139 |
|
| 51304 |
jmc |
140 |
The \code{signature} argument to \code{dumpMethods} is ignored (it
|
|
|
141 |
was used internally in previous implementations).}
|
|
|
142 |
|
| 44809 |
maechler |
143 |
\item{file}{ The file or connection on which to dump method definitions. }
|
| 17000 |
jmc |
144 |
|
|
|
145 |
\item{def}{ The function object defining the method; if omitted, the
|
|
|
146 |
current method definition corresponding to the signature. }
|
|
|
147 |
|
| 17262 |
hornik |
148 |
\item{\dots}{Named or unnamed arguments to form a signature.}
|
| 17000 |
jmc |
149 |
|
|
|
150 |
\item{generic}{In testing or finding functions, should generic
|
|
|
151 |
functions be included. Supply as \code{FALSE} to get only
|
|
|
152 |
non-generic functions.}
|
|
|
153 |
|
|
|
154 |
\item{fdef}{Optional, the generic function definition.
|
|
|
155 |
|
|
|
156 |
Usually omitted in calls to \code{isGeneric}}
|
| 31891 |
maechler |
157 |
|
| 17000 |
jmc |
158 |
\item{getName}{If \code{TRUE}, \code{isGeneric} returns the name of
|
|
|
159 |
the generic. By default, it returns \code{TRUE}. }
|
|
|
160 |
\item{methods}{
|
|
|
161 |
The methods object containing the methods to be dumped. By default,
|
|
|
162 |
the methods defined for this generic (optionally on the specified
|
|
|
163 |
\code{where} location).
|
|
|
164 |
}
|
| 33659 |
maechler |
165 |
\item{all}{in \code{removeMethods}, logical indicating if all
|
|
|
166 |
(default) or only the first method found should be removed.}
|
| 33723 |
ripley |
167 |
\item{searchForm}{In \code{getGenerics}, if \code{TRUE}, the
|
|
|
168 |
\code{package} slot of the returned result is in the form used
|
|
|
169 |
by \code{search()}, otherwise as the simple package name (e.g,
|
|
|
170 |
\code{"package:base"} vs \code{"base"}).
|
| 33659 |
maechler |
171 |
}
|
| 17000 |
jmc |
172 |
}
|
|
|
173 |
|
| 17211 |
jmc |
174 |
\section{Details}{
|
| 17000 |
jmc |
175 |
\describe{
|
| 31891 |
maechler |
176 |
\item{\code{isGeneric}:}{
|
| 19029 |
hornik |
177 |
If the \code{fdef} argument is supplied, take this as the
|
|
|
178 |
definition of the generic, and test whether it is really a
|
|
|
179 |
generic, with \code{f} as the name of the generic. (This argument
|
|
|
180 |
is not available in S-Plus.)
|
|
|
181 |
}
|
| 31891 |
maechler |
182 |
\item{\code{removeGeneric}:}{
|
| 19029 |
hornik |
183 |
If \code{where} supplied, just remove the version on this element
|
|
|
184 |
of the search list; otherwise, removes the first version
|
|
|
185 |
encountered.
|
|
|
186 |
}
|
| 31891 |
maechler |
187 |
\item{\code{standardGeneric}:}{
|
| 19029 |
hornik |
188 |
Generic functions should usually have a call to
|
|
|
189 |
\code{standardGeneric} as their entire body. They can, however,
|
|
|
190 |
do any other computations as well.
|
| 17000 |
jmc |
191 |
|
| 19029 |
hornik |
192 |
The usual \code{setGeneric} (directly or through calling
|
|
|
193 |
\code{setMethod}) creates a function with a call to
|
|
|
194 |
\code{standardGeneric}.
|
|
|
195 |
}
|
| 31891 |
maechler |
196 |
\item{\code{dumpMethod}:}{
|
| 19029 |
hornik |
197 |
The resulting source file will recreate the method.
|
|
|
198 |
}
|
| 31891 |
maechler |
199 |
\item{\code{findFunction}:}{
|
| 19029 |
hornik |
200 |
If \code{generic} is \code{FALSE}, ignore generic functions.
|
|
|
201 |
}
|
| 31891 |
maechler |
202 |
\item{\code{dumpMethods}:}{
|
| 19029 |
hornik |
203 |
If \code{signature} is supplied only the methods matching this
|
|
|
204 |
initial signature are dumped. (This feature is not found in
|
|
|
205 |
S-Plus: don't use it if you want compatibility.)
|
|
|
206 |
}
|
| 31891 |
maechler |
207 |
\item{\code{signature}:}{
|
| 19029 |
hornik |
208 |
The advantage of using \code{signature} is to provide a check on
|
|
|
209 |
which arguments you meant, as well as clearer documentation in
|
|
|
210 |
your method specification. In addition, \code{signature} checks
|
|
|
211 |
that each of the elements is a single character string.
|
|
|
212 |
}
|
| 31891 |
maechler |
213 |
\item{\code{removeMethods}:}{
|
| 19029 |
hornik |
214 |
Returns \code{TRUE} if \code{f} was a generic function,
|
|
|
215 |
\code{FALSE} (silently) otherwise.
|
| 31891 |
maechler |
216 |
|
| 19029 |
hornik |
217 |
If there is a default method, the function will be re-assigned as
|
| 20676 |
jmc |
218 |
a simple function with this definition.
|
|
|
219 |
Otherwise, the generic function remains but with no methods (so
|
|
|
220 |
any call to it will generate an error). In either case, a
|
|
|
221 |
following call to \code{setMethod} will consistently
|
|
|
222 |
re-establish the same generic function as before.
|
| 19029 |
hornik |
223 |
}
|
| 17000 |
jmc |
224 |
}
|
|
|
225 |
}
|
|
|
226 |
\references{
|
| 71548 |
jmc |
227 |
Chambers, John M. (2016)
|
|
|
228 |
\emph{Extending R},
|
|
|
229 |
Chapman & Hall.
|
|
|
230 |
(Chapters 9 and 10.)
|
|
|
231 |
}
|
| 17000 |
jmc |
232 |
|
| 19029 |
hornik |
233 |
\seealso{
|
| 33634 |
maechler |
234 |
\code{\link{getMethod}} (also for \code{selectMethod}),
|
| 19029 |
hornik |
235 |
\code{\link{setGeneric}},
|
|
|
236 |
\code{\link{setClass}},
|
|
|
237 |
\code{\link{showMethods}}
|
|
|
238 |
}
|
| 22294 |
jmc |
239 |
\examples{
|
| 41513 |
ripley |
240 |
require(stats) # for lm
|
| 33659 |
maechler |
241 |
|
|
|
242 |
## get the function "myFun" -- throw an error if 0 or > 1 versions visible:
|
|
|
243 |
findFuncStrict <- function(fName) {
|
|
|
244 |
allF <- findFunction(fName)
|
| 25351 |
jmc |
245 |
if(length(allF) == 0)
|
| 33659 |
maechler |
246 |
stop("No versions of ",fName," visible")
|
| 25351 |
jmc |
247 |
else if(length(allF) > 1)
|
| 33659 |
maechler |
248 |
stop(fName," is ambiguous: ", length(allF), " versions")
|
| 25351 |
jmc |
249 |
else
|
| 33659 |
maechler |
250 |
get(fName, allF[[1]])
|
| 25351 |
jmc |
251 |
}
|
| 31891 |
maechler |
252 |
|
| 33663 |
maechler |
253 |
try(findFuncStrict("myFun"))# Error: no version
|
| 33659 |
maechler |
254 |
lm <- function(x) x+1
|
| 33663 |
maechler |
255 |
try(findFuncStrict("lm"))# Error: 2 versions
|
| 33662 |
maechler |
256 |
findFuncStrict("findFuncStrict")# just 1 version
|
| 33663 |
maechler |
257 |
rm(lm)
|
| 33659 |
maechler |
258 |
|
| 26000 |
ripley |
259 |
\dontshow{
|
| 22294 |
jmc |
260 |
## because nosegfault runs standardGeneric w/o the methods package, nothing
|
|
|
261 |
## really gets tested. The following check that it catches some errors
|
| 49719 |
maechler |
262 |
mustDie <- function(expr)
|
|
|
263 |
stopifnot(is(tryCatch(expr, error=function(e)e), "error"))
|
| 22294 |
jmc |
264 |
|
|
|
265 |
mustDie(standardGeneric()) # 3 tests of requiring a single string
|
|
|
266 |
mustDie(standardGeneric(NULL))
|
|
|
267 |
mustDie(standardGeneric(""))
|
|
|
268 |
mustDie(standardGeneric("notAGenericFunction"))
|
|
|
269 |
mustDie(standardGeneric("show")) # a generic, but not called from its body
|
|
|
270 |
}
|
| 44809 |
maechler |
271 |
|
|
|
272 |
## method dumping ------------------------------------
|
|
|
273 |
|
| 71228 |
maechler |
274 |
setClass("A", slots = c(a="numeric"))
|
| 44809 |
maechler |
275 |
setMethod("plot", "A", function(x,y,...){ cat("A meth\n") })
|
|
|
276 |
dumpMethod("plot","A", file="")
|
|
|
277 |
\dontrun{
|
|
|
278 |
setMethod("plot", "A",
|
|
|
279 |
function (x, y, ...)
|
|
|
280 |
{
|
|
|
281 |
cat("AAAAA\n")
|
| 22294 |
jmc |
282 |
}
|
| 44809 |
maechler |
283 |
)
|
|
|
284 |
}%dont
|
|
|
285 |
tmp <- tempfile()
|
|
|
286 |
dumpMethod("plot","A", file=tmp)
|
|
|
287 |
## now remove, and see if we can parse the dump
|
|
|
288 |
stopifnot(removeMethod("plot", "A"))
|
|
|
289 |
source(tmp)
|
|
|
290 |
stopifnot(is(getMethod("plot", "A"), "MethodDefinition"))
|
|
|
291 |
|
|
|
292 |
## same with dumpMethods() :
|
|
|
293 |
setClass("B", contains="A")
|
|
|
294 |
setMethod("plot", "B", function(x,y,...){ cat("B ...\n") })
|
|
|
295 |
dumpMethods("plot", file=tmp)
|
|
|
296 |
stopifnot(removeMethod("plot", "A"),
|
|
|
297 |
removeMethod("plot", "B"))
|
|
|
298 |
source(tmp)
|
|
|
299 |
stopifnot(is(getMethod("plot", "A"), "MethodDefinition"),
|
|
|
300 |
is(getMethod("plot", "B"), "MethodDefinition"))
|
|
|
301 |
}
|
| 17000 |
jmc |
302 |
\keyword{programming}
|
|
|
303 |
\keyword{classes}
|
|
|
304 |
\keyword{methods}
|