Validatoren und Hilfsfunktionen
Teil des Abschnitts Objektorientierte Programmierung der R-Journey von Coddy. Lektion 5 von 57.
Der Konstruktor prüft Typen; ein Validator prüft Werte. Konventionell nimmt validate_money() ein Objekt entgegen, ruft für jede verletzte Regel stop() mit einer eindeutigen Meldung auf und gibt das Objekt zurück, wenn alles in Ordnung ist. call. = FALSE verhindert, dass der Funktionsaufruf in der Meldung erscheint:
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"))Ausgabe:
Error: amount must not be negative
Execution haltedDer Hilfswrapper ist die Funktion, die von anderem Code aufgerufen wird. Sie ist nach der Klasse benannt, konvertiert ihre Eingabe in die richtigen Typen, ergänzt Standardwerte und leitet das Ergebnis durch den Konstruktor und den Validator:
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)Ausgabe:
12 USDCode, das Benutzereingaben liest, fängt die Fehler des Validators mit tryCatch() ab und zeigt conditionMessage(e) an, den an stop() übergebenen Text:
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")
}Ausgabe:
ok 30
age must not be negative
age is too large Jede der drei Funktionen hat eine Aufgabe. new_money() ist streng und schnell und eignet sich für Code, der bereits die richtigen Typen hat. validate_money() enthält die Regeln für Werte, die langsam oder zahlreich sein können. money() ist benutzerfreundlich und wird vom restlichen Programm verwendet:
new_money() # nur Typen; baut das Objekt mit structure()
validate_money() # Wertregeln; stop() mit einer Nachricht, sonst return x
money() # konvertiert die Eingabe, dann validate_money(new_money(...))Aufgabe
Einfachnew_score(points, max) in Score.R erstellt ein score-Objekt. Vervollständige die anderen Funktionen in derselben Datei:
validate_score(x)bricht mitpoints must not be negative,max must be positiveoderpoints must not exceed maxab, und zwar in dieser Reihenfolge geprüft, und gibt andernfallsxzurück.score(points, max = 100)konvertiert beide Argumente mitas.double()und gibtvalidate_score(new_score(...))zurück.format.score(x, ...)gibt45/50 (90%)zurück, wobei der Prozentsatz auf eine ganze Zahl gerundet wird.
Verwende in jedem stop() call. = FALSE. Der bereitgestellte Code liest Zeilen wie 45 50, gibt die formatierte Punktzahl oder error: und die Nachricht aus.
Dein Code gehört in Score.R. main.R enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
source("Score.R")
# Mitgelieferter Ein-/Ausgabe-Code: belasse ihn wie er ist
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 = "")
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1S3-Grundlagen
Arbeiten mit DateienListen mit einer KlasseKonstruktorfunktionenPrint- und Format-MethodenValidatoren und HilfsfunktionenRückblick – Temperaturen4Kapselung in R
Closures als ObjekteUmgebungen als ObjekteZugriffsfunktionenZustand schützenRückblick – Parkuhr2S3-Generics und Methoden
Generics und UseMethodStandardmethodenMethoden für Basis-GenericsGrundlagen von NextMethodWiederholung – Flächeninhalte von Formen5S4-Klassen
S4-Klassen definierenSlots und ZugriffGültigkeitsprüfungenShow-MethodenRückblick – Produktkatalog8Referenzklassen
Referenzklassen definierenMethoden und FeldänderungenKopiersemantikVererbung und callSuperZusammenfassung – Aufgabenwarteschlange11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Online-R-Compiler