Walidatory i funkcje pomocnicze
Część sekcji Programowanie obiektowe ścieżki R w Coddy. Lekcja 5 z 57.
Konstruktor sprawdza typy; walidator sprawdza wartości. Zgodnie z konwencją validate_money() przyjmuje obiekt, wywołuje stop() z jasnym komunikatem dla każdej naruszonej reguły i zwraca obiekt, gdy wszystko jest w porządku. call. = FALSE sprawia, że wywołanie funkcji nie pojawia się w komunikacie:
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"))Wynik:
Error: amount must not be negative
Execution haltedFunkcja pomocnicza to funkcja wywoływana przez inny kod. Jej nazwa pochodzi od nazwy klasy, konwertuje dane wejściowe na odpowiednie typy, uzupełnia wartości domyślne i przekazuje wynik do konstruktora oraz walidatora:
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)Wynik:
12 USDKod, który odczytuje dane wejściowe użytkownika, przechwytuje błędy walidatora za pomocą tryCatch() i wyświetla conditionMessage(e), czyli tekst przekazany do 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")
}Wynik:
ok 30
age must not be negative
age is too large Każda z trzech funkcji ma jedno zadanie. new_money() jest rygorystyczna i szybka, przeznaczona do kodu, który ma już właściwe typy. validate_money() zawiera reguły dotyczące wartości, których sprawdzanie może być powolne lub może być ich wiele. money() jest przyjazna i to jej używa reszta programu:
new_money() # tylko typy; tworzy obiekt za pomocą structure()
validate_money() # reguły dotyczące wartości; wywołuje stop() z komunikatem, w przeciwnym razie zwraca x
money() # konwertuje dane wejściowe, a następnie wywołuje validate_money(new_money(...))Wyzwanie
Łatwynew_score(points, max) w pliku Score.R tworzy obiekt score. Uzupełnij pozostałe funkcje w tym samym pliku:
validate_score(x)zgłasza błąd z komunikatempoints must not be negative,max must be positivelubpoints must not exceed max, sprawdzając je w tej kolejności, a w przeciwnym razie zwracax.score(points, max = 100)konwertuje oba argumenty za pomocąas.double()i zwracavalidate_score(new_score(...)).format.score(x, ...)zwraca45/50 (90%), zaokrąglając procent do liczby całkowitej.
Użyj call. = FALSE w każdym wywołaniu stop(). Dostarczony kod odczytuje wiersz 45 50, wyświetla sformatowany wynik albo error: i komunikat.
Twój kod umieść w pliku Score.R. Plik main.R zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
source("Score.R")
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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 = "")
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy S3
Praca z plikamiListy z klasąFunkcje konstruktoraMetody print i formatWalidatory i funkcje pomocniczePowtórzenie — temperatury4Enkapsulacja w R
Domknięcia jako obiektyŚrodowiska jako obiektyFunkcje dostępoweOchrona stanuPodsumowanie – parkometr2Generics i metody S3
Generics i UseMethodMetody domyślneMetody dla podstawowych genericsPodstawy NextMethodPowtórzenie — pola figur5Klasy S4
Definiowanie klas S4Sloty i dostępSprawdzanie poprawnościMetody wyświetlaniaPodsumowanie – katalog produktów8Klasy referencyjne
Definiowanie klas referencyjnychMetody i aktualizacja pólSemantyka kopiowaniaDziedziczenie i callSuperPodsumowanie – kolejka zadań11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książek3Dziedziczenie S3
Wektory klasKolejność wyszukiwania metodRozszerzanie za pomocą NextMethodSprawdzanie za pomocą inherits()Powtórzenie — lista płac pracownikówPoćwicz samodzielnie: Kompilator R online