13.4 Generics and methods
Generic functions:
- Consist of a call to
UseMethod()
- Pass arguments from the generic to the dispatched method “auto-magically”
13.4.1 Method dispatch
UseMethod()
creates a vector of method names- Dispatch
- Examines all methods in the vector
- Selects a method
13.4.2 Finding methods
While sloop::s3_dispatch()
gives the specific method selected for a specific call, on can see the methods defined:
- For a generic
sloop::s3_methods_generic("mean")
#> # A tibble: 9 × 4
#> generic class visible source
#> <chr> <chr> <lgl> <chr>
#> 1 mean bench_time FALSE registered S3method
#> 2 mean Date TRUE base
#> 3 mean default TRUE base
#> 4 mean difftime TRUE base
#> 5 mean integer64 FALSE registered S3method
#> 6 mean POSIXct TRUE base
#> 7 mean POSIXlt TRUE base
#> 8 mean quosure FALSE registered S3method
#> 9 mean vctrs_vctr FALSE registered S3method
- For a class
sloop::s3_methods_class("ordered")
#> # A tibble: 6 × 4
#> generic class visible source
#> <chr> <chr> <lgl> <chr>
#> 1 as.data.frame ordered TRUE base
#> 2 Ops ordered TRUE base
#> 3 relevel ordered FALSE registered S3method
#> 4 scale_type ordered FALSE registered S3method
#> 5 Summary ordered TRUE base
#> 6 type_sum ordered FALSE registered S3method
13.4.3 Creating methods
Two rules:
- Only write a method if you own the generic. Otherwise, bad manners.
- Method must have same arguments as its generic–with one important exception:
...
Example from text:
I thought it would be good for us to work through this problem.
Carefully read the documentation for
UseMethod()
and explain why the following code returns the results that it does. What two usual rules of function evaluation doesUseMethod()
violate?
g <- function(x) {
x <- 10
y <- 10
UseMethod("g")
}
g.default <- function(x) c(x = x, y = y)
x <- 1
y <- 1
g(x)
#> x y
#> 1 1
g.default(x)
#> x y
#> 1 1
Examples caught in the wild:
haven::zap_label
, which removes column labelsdplyr::mutate
tidyr::pivot_longer