Les fermetures comme objets
Fait partie de la section Programmation orientée objet du Journey R de Coddy. Leçon 17 sur 57.
Vous avez découvert les fermetures dans Logic & Flow : une fonction créée à l'intérieur d'une autre fonction conserve les variables qui l'entourent. Une fabrique de fonctions qui renvoie une liste de telles fonctions construit un objet. Ses variables locales constituent les données de l'objet, et les fonctions en sont les méthodes :
make_account <- function(balance = 0) {
deposit <- function(x) balance <<- balance + x
get_balance <- function() balance
list(deposit = deposit, get_balance = get_balance)
}
acc <- make_account(100)
acc$deposit(50)
print(acc$get_balance())Résultat :
[1] 150Chaque appel de la fabrique réexécute son corps, de sorte que chaque objet possède ses propres variables. Modifier un compte ne modifie pas l’autre :
make_account <- function(balance = 0) {
list(deposit = function(x) balance <<- balance + x,
get_balance = function() balance)
}
ada <- make_account(100)
bo <- make_account(5)
ada$deposit(1)
cat(ada$get_balance(), bo$get_balance())Résultat :
101 5Les données sont privées. balance n’est pas un élément de la liste, donc acc$balance vaut NULL et lui affecter une valeur ne fait qu’ajouter un élément sans rapport. Les fonctions de la liste constituent toute l’interface publique de l’objet :
make_account <- function(balance = 0) {
list(get_balance = function() balance)
}
acc <- make_account(100)
print(acc$balance)
acc$balance <- 1e6
print(acc$get_balance())Sortie :
NULL
[1] 100Les méthodes peuvent s’appeler les unes les autres lorsqu’elles sont définies comme fonctions locales avant la construction de la liste. Ici, add_many() réutilise add() :
make_tally <- function() {
total <- 0
add <- function(x) total <<- total + x
add_many <- function(xs) for (x in xs) add(x)
get <- function() total
list(add = add, add_many = add_many, get = get)
}
t <- make_tally()
t$add(1)
t$add_many(c(2, 3, 4))
print(t$get())Sortie :
[1] 10Défi
FacileComplétez la fabrique make_counter(start = 0) dans Counter.R. Elle conserve la valeur actuelle privée et renvoie une liste contenant quatre fonctions : increment() et decrement() modifient la valeur de 1, reset() la rétablit à start, et value() la renvoie.
Le code fourni lit la valeur de départ, puis les commandes +, - ou reset, et affiche la valeur après chacune d’elles. À la fin, il affiche les noms présents dans la liste renvoyée, qui ne doit contenir que les quatre fonctions.
Votre code doit être placé dans Counter.R. main.R contient le code fourni pour les entrées et les sorties et ne peut pas être modifié.
Essayez vous-même
source("Counter.R")
# Code d'entrée/sortie fourni : le laisser tel quel
input <- suppressWarnings(readLines(file("stdin")))
counter <- make_counter(as.numeric(input[1]))
for (cmd in input[-1]) {
if (cmd == "+") counter$increment()
if (cmd == "-") counter$decrement()
if (cmd == "reset") counter$reset()
cat(cmd, " -> ", counter$value(), "\n", sep = "")
}
cat("fields visible: ", paste(sort(names(counter)), collapse = ", "), "\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