Menu
Coddy logo textTech

Fonctions d’accès

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

L'encapsulation signifie que les autres codes interagissent avec un objet par l'intermédiaire de fonctions au lieu d'accéder directement à ses champs. Un getter lit une valeur et un setter la modifie. Pour une liste S3, le setter renvoie la copie modifiée :

new_member <- function(name) structure(list(name = name), class = "member")
get_name <- function(p) p$name
set_name <- function(p, value) {
  p$name <- value
  p
}
p <- new_member("ada")
p <- set_name(p, "Ada Lovelace")
print(get_name(p))

Sortie :

[1] "Ada Lovelace"

Les accesseurs permettent à l’objet de modifier la manière dont il stocke les données sans casser le code qui l’utilise. Ce thermomètre stocke les degrés Celsius, et un accesseur calcule les degrés Fahrenheit lorsqu’on les demande, de sorte que les appelants ne voient jamais le champ lui-même :

new_thermo <- function(c) structure(list(c = c), class = "thermo")
celsius <- function(t) t$c
fahrenheit <- function(t) t$c * 9 / 5 + 32
t <- new_thermo(25)
cat(celsius(t), fahrenheit(t))

Sortie :

25 77

Les propres setters de R, tels que names(x) <- ..., sont des fonctions de remplacement. Une fonction nommée "name<-" avec les paramètres x et value permet aux appelants d’écrire name(p) <- "Bo" ; R l’appelle et réaffecte le résultat à p :

new_member <- function(name) structure(list(name = name), class = "member")
name <- function(p) p$name
"name<-" <- function(x, value) {
  x$name <- trimws(value)
  x
}
p <- new_member("ada")
name(p) <- "  Bo  "
print(name(p))

Sortie :

[1] "Bo"

Un accesseur d’un objet de fermeture renvoie une copie des données privées. Modifier cette copie ne modifie pas l’objet ; le seul moyen d’y accéder passe donc par les propres fonctions de l’objet :

make_list <- function() {
  items <- character(0)
  list(add = function(x) items <<- c(items, x),
       get_items = function() items)
}
todo <- make_list()
todo$add("milk")
mine <- todo$get_items()
mine[1] <- "HACKED"
print(todo$get_items())

Sortie :

[1] "milk"
challenge icon

Défi

Facile

Un contact est une liste S3 de classe contact avec les champs name et email. Complétez Contact.R :

  • new_contact(name, email) stocke l’adresse e-mail après suppression des espaces superflus et en minuscules.
  • Les accesseurs contact_name(x) et contact_email(x).
  • La fonction de remplacement "contact_email<-", qui stocke la nouvelle adresse e-mail après suppression des espaces superflus et en minuscules, afin que les appelants puissent écrire contact_email(c1) <- value.

Le code fourni lit name,email, puis de nouvelles adresses e-mail, et affiche Ada <ada@x.com> après chaque modification ainsi que les noms des champs stockés à la fin.

Votre code doit se trouver dans Contact.R. main.R contient le code fourni d’entrée/sortie et ne peut pas être modifié.

Essayez vous-même

source("Contact.R")

# Code d'entrée/sortie fourni : le garder tel quel
input <- suppressWarnings(readLines(file("stdin")))
p <- strsplit(input[1], ",")[[1]]
c1 <- new_contact(p[1], p[2])
cat(contact_name(c1), " <", contact_email(c1), ">\n", sep = "")
for (value in input[-1]) {
  contact_email(c1) <- value
  cat(contact_name(c1), " <", contact_email(c1), ">\n", sep = "")
}
cat("stored fields: ", paste(names(unclass(c1)), 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