28 agosto, 2021

Selo DC

POO: Sistema S3

Ideia básica internamente ao UseMethod()

## Primeiro argumento do generico
x <- 1:10
## Ideia sobre os potenciais metodos (UseMethod)
paste0("generic", ".", c(class(x), "default"))
## [1] "generic.integer" "generic.default"

Verificando o despacho

# Instalar o pacote 'sloop', se nao tiver!
# Objeto de classe 'data.frame'
x <- data.frame() 
# Despacho (envio) do generico 'print'
sloop::s3_dispatch(print(x))
## => print.data.frame
##  * print.default

Saída da chamada s3_dispactch()

O resultado da chamada sloop::s3_dispatch() pode apresentar três símbolos antes dos potenciais nomes de métodos:

  • =>: este símbolo indica que a função genérica despachou no referido método;
  • *: este símbolo indica que este método existe, mas a função genérica não despachou nele;
  • ->: indica o método herdado;

Aplicação

# Funcao generica
quem_sou_eu <- function(x, ...) UseMethod("quem_sou_eu")
# Metodo numero natural
quem_sou_eu.numero_natural <- function(x, ...){
  message("Eu sou um numero natural")
  NextMethod("quem_sou_eu")
}
# Metodo numerico
quem_sou_eu.numerico <- function(x, ...) message("Eu sou numerico")
# Objeto
x <- 1:10
# Classe
class(x) <- c("numero_complexo","numero_natural","numerico")
# Despacho
sloop::s3_dispatch(quem_sou_eu(x))
##    quem_sou_eu.numero_complexo
## => quem_sou_eu.numero_natural
## -> quem_sou_eu.numerico
##    quem_sou_eu.default

Funções primitivas genéricas

# Eh primitiva generica?
sloop::is_s3_generic("cbind")
## [1] TRUE
# Onde ocorre o despacho?
sloop::s3_dispatch(cbind(1:10))
##    cbind.integer
##    cbind.numeric
##    cbind.default
## => cbind (internal)

Genéricas de grupo

# Objeto de classe factor
x <- factor(1:5)
# Verificando o despacho de sqrt() do grupo 'Math'
sloop::s3_dispatch(sqrt(x))
##    sqrt.factor
##    sqrt.default
## => Math.factor
##    Math.default
##  * sqrt (internal)
# Verificando o metodo Math.factor()
Math.factor
## function (x, ...) 
## stop(gettextf("%s not meaningful for factors", sQuote(.Generic)))
## <bytecode: 0x0000000006b11328>
## <environment: namespace:base>

Bons estudos!