Validatori e funzioni di supporto
Fa parte della sezione Programmazione orientata agli oggetti del percorso R di Coddy. Lezione 5 di 57.
Il costruttore controlla i tipi; un validatore controlla i valori. Per convenzione, validate_money() prende un oggetto, chiama stop() con un messaggio chiaro per ogni regola violata e restituisce l’oggetto quando è tutto a posto. call. = FALSE evita che la chiamata alla funzione compaia nel messaggio:
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"))Output:
Error: amount must not be negative
Execution haltedLa funzione ausiliaria è la funzione che viene chiamata da altro codice. Prende il nome dalla classe, converte il suo input nei tipi corretti, inserisce i valori predefiniti e passa il risultato al costruttore e al validatore:
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)Output:
12 USDIl codice che legge l'input dell'utente intercetta gli errori del validatore con tryCatch() e mostra conditionMessage(e), il testo passato a 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")
}Output:
ok 30
age must not be negative
age is too large Ognuna delle tre funzioni ha un compito. new_money() è rigorosa e veloce, per il codice che ha già i tipi corretti. validate_money() contiene le regole sui valori, che possono essere lente da controllare o numerose. money() è intuitiva ed è ciò che usa il resto del programma:
new_money() # solo tipi; costruisce l'oggetto con structure()
validate_money() # regole sui valori; stop() con un messaggio, altrimenti restituisce x
money() # converte l'input, poi validate_money(new_money(...))Sfida
Facilenew_score(points, max) in Score.R crea un oggetto score. Completa le altre funzioni nello stesso file:
validate_score(x)si interrompe conpoints must not be negative,max must be positiveoppurepoints must not exceed max, verificando in quest'ordine; altrimenti restituiscex.score(points, max = 100)converte entrambi gli argomenti conas.double()e restituiscevalidate_score(new_score(...)).format.score(x, ...)restituisce45/50 (90%), con la percentuale arrotondata a un numero intero.
Usa call. = FALSE in ogni stop(). Il codice fornito legge le righe 45 50, stampa il punteggio formattato oppure error: e il messaggio.
Il tuo codice va in Score.R. main.R contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
source("Score.R")
# Supplied input/output code: keep it as it is
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 = "")
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Nozioni di base su S3
Lavorare con i fileListe con una classeFunzioni costruttriciMetodi di stampa e formattazioneValidatori e funzioni di supportoRipasso - Temperature4Incapsulamento in R
Chiusure come oggettiAmbienti come oggettiFunzioni di accessoProteggere lo statoRiepilogo - Parcometro2Generics e metodi S3
Generics e UseMethodMetodi predefinitiMetodi per i generics di baseNozioni di base su NextMethodRiepilogo - Aree delle forme5Classi S4
Definire le classi S4Slot e accessoControlli di validitàMetodi showRiepilogo - Catalogo prodotti8Classi di riferimento
Definizione delle classi di riferimentoMetodi e aggiornamenti dei campiSemantica della copiaEreditarietà e callSuperRiepilogo - coda di attività11Progetto: Gestione della biblioteca
Libri e iscrittiPrestito dei libriEsercitati da solo: Compilatore R online