Funzioni costruttrici
Fa parte della sezione Programmazione orientata agli oggetti del percorso R di Coddy. Lezione 3 di 57.
Poiché R non controlla mai i campi di un oggetto S3, ogni oggetto di una classe dovrebbe essere creato da una sola funzione, il suo costruttore. Per convenzione, il costruttore di basso livello si chiama new_ seguito dal nome della classe. Accetta ogni campo come argomento, ne controlla i tipi con stopifnot() e restituisce l'oggetto:
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)Output:
9.5 EURstopifnot() interrompe il programma quando una delle sue condizioni non è TRUE, e il messaggio indica il controllo non superato. Un tipo errato viene rilevato nel momento in cui l’oggetto viene creato, non in seguito, quando viene usato da un’altra funzione:
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")Output:
Error in new_money("9.5", "EUR") : is.double(amount) is not TRUE
Calls: new_money -> stopifnot
Execution haltedIl costruttore è l’unico punto in cui viene chiamata structure() per la classe, quindi ogni oggetto ha gli stessi campi nello stesso ordine. Il codice che ha bisogno di molti oggetti la chiama in un ciclo o con 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")Output:
1 1
2 4
3 9 Un oggetto S3 non deve necessariamente essere una lista. Un costruttore può assegnare un'etichetta a un vettore semplice e memorizzare informazioni aggiuntive come attributi, come avviene per i fattori e le date di R. attr(x, "unit") legge un attributo:
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)Output:
[1] "km"
[1] 2000Sfida
FacileCompleta il costruttore new_book(title, author, pages) in Book.R. Verifica con stopifnot() che title e author siano caratteri e che pages sia numerico, quindi restituisce una lista con questi tre campi e la classe book. Poi completa book_label(b), che restituisce Dune by Frank Herbert, 412 pages.
Il codice fornito legge righe title;author;pages. Passa pages come numero quando è composto da cifre e come testo originale altrimenti, stampa book: e l'etichetta per ogni oggetto, e stampa rejected: e il titolo quando il costruttore si interrompe.
Il tuo codice va in Book.R. main.R contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
source("Book.R")
# Supplied input/output code: keep it as it is
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 = "")
}
}
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