Validadores e Auxiliares
Parte da seção Programação Orientada a Objetos do Journey de R da Coddy. Lição 5 de 57.
O construtor verifica tipos; um validador verifica valores. Por convenção, validate_money() recebe um objeto, chama stop() com uma mensagem clara para cada regra que ele viola e retorna o objeto quando tudo está correto. call. = FALSE mantém a chamada da função fora da mensagem:
new_money <- function(amount = double(), currency = character()) {
stopifnot(is.double(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
validate_money <- function(x) {
if (x$amount < 0) stop("amount must not be negative", call. = FALSE)
if (nchar(x$currency) != 3) stop("currency must have 3 letters", call. = FALSE)
x
}
m <- validate_money(new_money(-5, "EUR"))Saída:
Error: amount must not be negative
Execution haltedO auxiliar é a função que outro código chama. Ele recebe o nome da classe, converte sua entrada para os tipos corretos, preenche os valores padrão e passa o resultado pelo construtor e pelo validador:
new_money <- function(amount = double(), currency = character()) {
stopifnot(is.double(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
validate_money <- function(x) {
if (x$amount < 0) stop("amount must not be negative", call. = FALSE)
x
}
money <- function(amount, currency = "EUR") {
validate_money(new_money(as.double(amount), toupper(currency)))
}
m <- money("12", "usd")
cat(m$amount, m$currency)Saída:
12 USDO código que lê a entrada do usuário captura os erros do validador com tryCatch() e exibe conditionMessage(e), o texto passado para stop():
validate_age <- function(x) {
if (x$years < 0) stop("age must not be negative", call. = FALSE)
if (x$years > 150) stop("age is too large", call. = FALSE)
x
}
age <- function(years) validate_age(structure(list(years = as.double(years)), class = "age"))
for (input in c("30", "-2", "200")) {
result <- tryCatch(paste("ok", age(input)$years), error = function(e) conditionMessage(e))
cat(result, "\n")
}Saída:
ok 30
age must not be negative
age is too large Cada uma das três funções tem uma tarefa. new_money() é rigorosa e rápida, para código que já tem os tipos corretos. validate_money() contém as regras sobre os valores, que podem ser lentas ou numerosas. money() é amigável e é usada pelo restante do programa:
new_money() # apenas tipos; constrói o objeto com structure()
validate_money() # regras de valor; stop() com uma mensagem, senão retorna x
money() # converte a entrada, depois validate_money(new_money(...))Desafio
Fácilnew_score(points, max) em Score.R cria um objeto score. Complete as outras funções no mesmo arquivo:
validate_score(x)interrompe compoints must not be negative,max must be positiveoupoints must not exceed max, verificadas nessa ordem, e caso contrário retornax.score(points, max = 100)converte ambos os argumentos comas.double()e retornavalidate_score(new_score(...)).format.score(x, ...)retorna45/50 (90%), com a porcentagem arredondada para um número inteiro.
Use call. = FALSE em cada stop(). O código fornecido lê linhas 45 50, imprime a pontuação formatada ou error: e a mensagem.
Seu código deve ficar em Score.R. main.R contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
source("Score.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]]
s <- tryCatch(score(p[1], p[2]), error = function(e) conditionMessage(e))
if (is.character(s)) cat("error: ", s, "\n", sep = "") else cat(format(s), "\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