Menu
Coddy logo textTech

Définition des classes de référence

Fait partie de la section Programmation orientée objet du Journey R de Coddy. Leçon 37 sur 57.

Les classes de référence (RC) constituent le système de R pour les objets qui se modifient sur place, comme en Java ou en Python. setRefClass() déclare une classe avec des champs typés et renvoie un générateur ; $new() crée un objet, et $ lit et modifie ses champs :

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
a <- Account$new(owner = "Ada", balance = 100)
a$balance <- a$balance + 50
cat(a$owner, a$balance)

Sortie :

Ada 150

Un objet RC est une référence, comme un environnement. L’affecter à une autre variable ou le transmettre à une fonction ne le copie pas ; ainsi, une modification effectuée via n’importe quel nom modifie l’unique objet :

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
pay_fee <- function(acc) acc$balance <- acc$balance - 5
a <- Account$new(owner = "Ada", balance = 100)
b <- a
b$balance <- 60
pay_fee(a)
cat(a$balance, b$balance)

Sortie :

55 55

Les champs sont typés. L’affectation d’une valeur de classe incorrecte est refusée et le champ conserve son ancienne valeur :

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
a <- Account$new(owner = "Ada", balance = 100)
msg <- tryCatch({ a$balance <- "lots"; "changed" }, error = function(e) conditionMessage(e))
cat(msg, "\n")
cat(a$balance, "\n")

Sortie :

invalid assignment for reference class field ‘balance’, should be from class “numeric” or a subclass (was class “character”) 
100 

Le générateur décrit la classe : Account$fields() liste les champs et leurs types. Un objet affiché sans méthode show liste ses champs ; un champ auquel aucune valeur n’a été attribuée est vide :

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
print(Account$fields())
Account$new(owner = "Bo")

Sortie :

      owner     balance 
"character"   "numeric" 
Reference class object of class "Account"
Field "owner":
[1] "Bo"
Field "balance":
numeric(0)
challenge icon

Défi

Facile

Déclarez la classe de référence Book dans Book.R avec les champs title et author (caractère) ainsi que pages (numérique), et conservez le générateur dans Book. Écrivez ensuite add_pages(book, n), qui ajoute n aux pages du livre sur place et ne renvoie rien d’utile.

Le code fourni lit title;author;pages, crée le livre, le transmet à une seconde variable, ajoute les nombres restants via ce second nom, puis affiche le livre d’origine et les noms des champs.

Votre code doit être placé dans Book.R. main.R contient le code fourni d’entrée/sortie 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")))
p <- strsplit(input[1], ";")[[1]]
b <- Book$new(title = p[1], author = p[2], pages = as.numeric(p[3]))
alias <- b
for (n in as.numeric(input[-1])) add_pages(alias, n)
cat(b$title, " by ", b$author, ": ", b$pages, " pages\n", sep = "")
cat("fields: ", paste(names(Book$fields()), collapse = ", "), "\n", sep = "")
quiz iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur R en ligne