## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----setup-------------------------------------------------------------------- library(S7) ## ----------------------------------------------------------------------------- mean <- new_generic("mean", "x") method(mean, class_numeric) <- function(x) sum(x) / length(x) ## ----error = TRUE, eval = FALSE----------------------------------------------- # mean(100, na.rm = TRUE) ## ----------------------------------------------------------------------------- method(mean, class_numeric) <- function(x, na.rm = TRUE) { if (na.rm) { x <- x[!is.na(x)] } sum(x) / length(x) } mean(c(100, NA), na.rm = TRUE) ## ----------------------------------------------------------------------------- simple_print <- new_generic("simple_print", "x") method(simple_print, class_double) <- function(x, digits = 3) {} method(simple_print, class_character) <- function(x, max_length = 100) {} ## ----------------------------------------------------------------------------- method(simple_print, class_list) <- function(x, ...) { for (el in x) { simple_print(el, ...) } } ## ----error = TRUE, eval = FALSE----------------------------------------------- # simple_print(list(1, 2, 3), digits = 3) # simple_print(list(1, 2, "x"), digits = 3) ## ----------------------------------------------------------------------------- method(simple_print, class_double) <- function(x, ..., digits = 3) {} method(simple_print, class_character) <- function(x, ..., max_length = 100) {} simple_print(list(1, 2, "x"), digits = 3) ## ----------------------------------------------------------------------------- simple_print(list(1, 2, "x"), diggits = 3) ## ----eval = FALSE------------------------------------------------------------- # length <- new_generic("length", "x", function(x) { # S7_dispatch() # }) ## ----------------------------------------------------------------------------- display <- new_generic("display", "x") S7_data(display) ## ----------------------------------------------------------------------------- foo <- new_generic("foo", "x", function(x, y, ...) { S7_dispatch() }) ## ----------------------------------------------------------------------------- method(foo, class_integer) <- function(x, ...) { 10 } ## ----------------------------------------------------------------------------- mean <- new_generic("mean", "x", function(x, ..., na.rm = TRUE) { S7_dispatch() }) method(mean, class_integer) <- function(x, na.rm = TRUE) { if (na.rm) { x <- x[!is.na(x)] } sum(x) / length(x) } ## ----------------------------------------------------------------------------- method(mean, class_double) <- function(x, na.rm = FALSE) {} method(mean, class_logical) <- function(x) {} ## ----------------------------------------------------------------------------- mean <- new_generic("mean", "x", function(x, ..., na.rm = TRUE) { if (!identical(na.rm, TRUE) && !identical(na.rm = FALSE)) { stop("`na.rm` must be either TRUE or FALSE") } S7_dispatch() }) ## ----------------------------------------------------------------------------- mean <- new_generic("mean", "x") method(mean, class_numeric) <- function(x) { sum(x) / length(x) } mean(1:10) ## ----------------------------------------------------------------------------- date <- new_class("date", parent = class_double) # Cheat by using the existing base .Date class method(print, date) <- function(x) print(.Date(x)) date(c(1, 10, 100)) ## ----------------------------------------------------------------------------- method(mean, date) <- function(x) { date(mean(super(x, to = class_double))) } mean(date(c(1, 10, 100))) ## ----------------------------------------------------------------------------- Pet <- new_class("Pet") Dog <- new_class("Dog", Pet) Cat <- new_class("Cat", Pet) Language <- new_class("Language") English <- new_class("English", Language) French <- new_class("French", Language) speak <- new_generic("speak", c("x", "y")) method(speak, list(Dog, English)) <- function(x, y) "Woof" method(speak, list(Cat, English)) <- function(x, y) "Meow" method(speak, list(Dog, French)) <- function(x, y) "Ouaf Ouaf" method(speak, list(Cat, French)) <- function(x, y) "Miaou" speak(Cat(), English()) speak(Dog(), French()) # This example was originally inspired by blog.klipse.tech/javascript/2021/10/03/multimethod.html # which has unfortunately since disappeared.