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