Skip to contents

A generic defines the interface of a function. Once you have created a generic with new_generic(), you provide implementations for specific signatures by registering methods with method<-.

The goal is for method<- to be the single function you need when working with S7 generics or S7 classes. This means that as well as registering methods for S7 classes on S7 generics, you can also register methods for S7 classes on S3 or S4 generics, and S3 or S4 classes on S7 generics. But this is not a general method registration function: at least one of generic and signature needs to be from S7.

Note that if you are writing a package, you must call S7_on_load() in your .onLoad. This ensures that all methods are dynamically registered when needed.

Usage

method(generic, signature) <- value

Arguments

generic

A generic function, i.e. an S7 generic, an external generic, an S3 generic, or an S4 generic.

Note that because method<- is an assignment function, method(pkg::gen, class) <- f will not work. You must either import gen into your namespace or use new_external_generic().

signature

A method signature.

For single-dispatch generics, this must be one of the following:

For generics that use multiple dispatch, this must be a list of any of the above types.

value

A function that implements the generic specification for the given signature, or NULL to unregister an existing method.

Value

Usually generic, invisibly.

When registering a method for a generic that lives in another package (an external, S3, or S4 generic), returns a sentinel object instead, to avoid embedding a copy of that generic in your package. See vignette("packages") for details.

Operators

Binary operators such as + and - dispatch on e1 and e2. To define a unary method, use list(Foo, class_missing) as the signature and a function with arguments e1 and e2; e2 will be missing when called. This lets unary and binary methods coexist on the same class.

The ! operator is always unary. Use Foo (or list(Foo)) as its signature and a function with argument e1.

If no unary method is registered, the operator falls back to R's base behavior for the underlying object. Errors raised inside a registered method are propagated.

Examples

# Create a generic
bizarro := new_generic("x")
# Register some methods
method(bizarro, class_numeric) <- function(x) rev(x)
method(bizarro, new_S3_class("data.frame")) <- function(x) {
  x[] <- lapply(x, bizarro)
  rev(x)
}

# Using a generic calls the methods automatically
bizarro(head(mtcars))
#>                   carb gear am vs  qsec    wt drat  hp disp cyl  mpg
#> Mazda RX4            1    3  0  1 20.22 3.460 2.76 105  225   6 18.1
#> Mazda RX4 Wag        2    3  0  0 17.02 3.440 3.15 175  360   8 18.7
#> Datsun 710           1    3  0  1 19.44 3.215 3.08 110  258   6 21.4
#> Hornet 4 Drive       1    4  1  1 18.61 2.320 3.85  93  108   4 22.8
#> Hornet Sportabout    4    4  1  0 17.02 2.875 3.90 110  160   6 21.0
#> Valiant              4    4  1  0 16.46 2.620 3.90 110  160   6 21.0

# Unregister a method by assigning `NULL`
method(bizarro, class_numeric) <- NULL