Funções Construtoras
Parte da seção Programação Orientada a Objetos do Journey de R da Coddy. Lição 3 de 57.
Como R nunca verifica os campos de um objeto S3, todo objeto de uma classe deve ser criado por uma única função, seu construtor. Por convenção, o construtor de baixo nível é chamado de new_ mais o nome da classe. Ele recebe cada campo como argumento, verifica os tipos com stopifnot() e retorna o objeto:
new_money <- function(amount = double(), currency = character()) {
stopifnot(is.double(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
m <- new_money(9.5, "EUR")
cat(m$amount, m$currency)Saída:
9.5 EURstopifnot() interrompe o programa quando uma de suas condições não é TRUE, e a mensagem nomeia a verificação que falhou. Um tipo incorreto é detectado no momento em que o objeto é construído, e não posteriormente, quando alguma outra função o utiliza:
new_money <- function(amount = double(), currency = character()) {
stopifnot(is.double(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
m <- new_money("9.5", "EUR")Saída:
Error in new_money("9.5", "EUR") : is.double(amount) is not TRUE
Calls: new_money -> stopifnot
Execution haltedO construtor é o único lugar que chama structure() para a classe, portanto todo objeto tem os mesmos campos na mesma ordem. O código que precisa de muitos objetos o chama em um loop ou com lapply():
new_point <- function(x = 0, y = 0) {
stopifnot(is.numeric(x), is.numeric(y))
structure(list(x = x, y = y), class = "point")
}
pts <- lapply(1:3, function(i) new_point(i, i * i))
for (p in pts) cat(p$x, p$y, "\n")Saída:
1 1
2 4
3 9 Um objeto S3 não precisa ser uma lista. Um construtor pode rotular um vetor simples e armazenar informações adicionais como atributos, que é assim que os próprios fatores e datas do R funcionam. attr(x, "unit") lê um atributo:
new_distance <- function(value = double(), unit = "m") {
stopifnot(is.double(value), is.character(unit))
structure(value, unit = unit, class = "distance")
}
d <- new_distance(c(1.5, 2), "km")
print(attr(d, "unit"))
print(unclass(d)[2] * 1000)Saída:
[1] "km"
[1] 2000Desafio
FácilComplete o construtor new_book(title, author, pages) em Book.R. Ele verifica com stopifnot() se title e author são do tipo caractere e se pages é numérico, e retorna uma lista com esses três campos e a classe book. Em seguida, complete book_label(b), que retorna Dune by Frank Herbert, 412 pages.
O código fornecido lê linhas no formato title;author;pages. Ele passa pages como um número quando é composto por dígitos e como o texto original caso contrário, imprime book: e o rótulo de cada objeto, e imprime rejected: e o título quando o construtor interrompe a execução.
Seu código deve estar em Book.R. main.R contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
source("Book.R")
# Código de entrada/saída fornecido: mantenha-o como está
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, ";")[[1]]
pages <- if (grepl("^[0-9]+$", p[3])) as.numeric(p[3]) else p[3]
b <- tryCatch(new_book(p[1], p[2], pages), error = function(e) NULL)
if (is.null(b)) {
cat("rejected: ", p[1], "\n", sep = "")
} else {
cat(class(b), ": ", book_label(b), "\n", sep = "")
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos do S3
Trabalhando com ArquivosListas com uma ClasseFunções ConstrutorasMétodos de Impressão e FormataçãoValidadores e AuxiliaresRevisão - Temperaturas4Encapsulamento em R
Closures como ObjetosAmbientes como ObjetosFunções de AcessoProtegendo o EstadoRecapitulação - Parquímetro2Genéricos e Métodos S3
Genéricos e UseMethodMétodos padrãoMétodos para genéricos baseFundamentos de NextMethodRevisão - Áreas de formas5Classes S4
Definindo classes S4Slots e acessoVerificações de validadeMétodos showRevisão - Catálogo de produtos8Classes de Referência
Definindo Classes de ReferênciaMétodos e Atualizações de CamposSemântica de CópiaHerança e callSuperRecapitulação — Fila de Tarefas11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Compilador de R online