Fonctions constructrices
Fait partie de la section Programmation orientée objet du Journey R de Coddy. Leçon 3 sur 57.
Comme R ne vérifie jamais les champs d’un objet S3, chaque objet d’une classe doit être créé par une seule fonction, son constructeur. Par convention, le constructeur de bas niveau est appelé new_ suivi du nom de la classe. Il prend chaque champ comme argument, vérifie les types avec stopifnot() et renvoie l’objet :
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)Sortie :
9.5 EURstopifnot() arrête le programme lorsque l’une de ses conditions n’est pas TRUE, et le message indique la vérification qui a échoué. Un type incorrect est détecté au moment où l’objet est créé, et non plus tard lorsqu’une autre fonction l’utilise :
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")Sortie :
Error in new_money("9.5", "EUR") : is.double(amount) is not TRUE
Calls: new_money -> stopifnot
Execution haltedLe constructeur est le seul endroit qui appelle structure() pour la classe, de sorte que chaque objet possède les mêmes champs dans le même ordre. Le code qui a besoin de nombreux objets l’appelle dans une boucle ou avec 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")Sortie :
1 1
2 4
3 9 Un objet S3 ne doit pas nécessairement être une liste. Un constructeur peut étiqueter un vecteur simple et stocker des informations supplémentaires sous forme d’attributs, ce qui explique le fonctionnement des facteurs et des dates de R. attr(x, "unit") lit un attribut :
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)Sortie :
[1] "km"
[1] 2000Défi
FacileComplétez le constructeur new_book(title, author, pages) dans Book.R. Il vérifie avec stopifnot() que title et author sont de type caractère et que pages est numérique, puis renvoie une liste contenant ces trois champs et la classe book. Complétez ensuite book_label(b), qui renvoie Dune by Frank Herbert, 412 pages.
Le code fourni lit des lignes title;author;pages. Il transmet pages sous forme de nombre lorsqu'il est composé de chiffres, et sous forme de texte original dans le cas contraire, affiche book: ainsi que le libellé de chaque objet, puis affiche rejected: et le titre lorsque le constructeur s'arrête.
Votre code doit être placé dans Book.R. main.R contient le code d'entrée/sortie fourni et ne peut pas être modifié.
Essayez vous-même
source("Book.R")
# Code d'entrée/sortie fourni : le garder tel quel
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 = "")
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Bases de S3
Travailler avec les fichiersListes avec une classeFonctions constructricesMéthodes print et formatValidateurs et fonctions utilitairesRécapitulatif - Températures4Encapsulation dans R
Les fermetures comme objetsLes environnements comme objetsFonctions d’accèsProtéger l’étatRécapitulatif - Parcmètre2S3 : génériques et méthodes
Génériques et UseMethodMéthodes par défautMéthodes pour les génériques de baseNotions de base sur NextMethodRécapitulatif - Aires des formes5Classes S4
Définir des classes S4Slots et accèsVérifications de validitéMéthodes showRécapitulatif - Catalogue de produits8Classes de référence
Définition des classes de référenceMéthodes et mises à jour des champsSémantique de copieHéritage et callSuperRécapitulatif - File d’attente des tâches11Projet : gestion de bibliothèque
Livres et membresEmprunter des livres3Héritage S3
Vecteurs de classesOrdre de recherche des méthodesÉtendre avec NextMethodVérifier avec inherits()Récapitulatif - Paie du personnelEntraînez-vous par vous-même : Compilateur R en ligne