Menu
Coddy logo textTech

Méthodes et mises à jour des champs

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

Les méthodes vont dans la liste methods de setRefClass(). À l’intérieur d’une méthode, les champs sont de simples noms, et <<- modifie un champ. Dans l’exécuteur Coddy, R affiche une note concernant le paquet optionnel codetools lorsqu’une classe avec des méthodes est définie ; enveloppe donc la définition dans suppressMessages() :

Counter <- suppressMessages(setRefClass("Counter",
  fields = list(count = "numeric"),
  methods = list(
    add = function(n = 1) {
      count <<- count + n
    },
    report = function() paste("count is", count)
  )
))
c1 <- Counter$new(count = 0)
c1$add()
c1$add(5)
print(c1$report())

Sortie :

[1] "count is 6"

.self est l’objet sur lequel la méthode a été appelée. Une méthode qui se termine par invisible(.self) renvoie l’objet, ce qui permet d’enchaîner les appels :

Counter <- suppressMessages(setRefClass("Counter",
  fields = list(count = "numeric"),
  methods = list(
    add = function(n = 1) {
      count <<- count + n
      invisible(.self)
    }
  )
))
c1 <- Counter$new(count = 0)
c1$add(2)$add(3)$add(4)
print(c1$count)

Résultat :

[1] 9

La méthode initialize s’exécute à l’intérieur de $new(). initFields(...) définit les champs qui ont été transmis  ensuite, la méthode peut attribuer des valeurs par défaut aux autres. Les méthodes s’appellent entre elles par leur nom :

Account <- suppressMessages(setRefClass("Account",
  fields = list(owner = "character", balance = "numeric"),
  methods = list(
    initialize = function(...) {
      initFields(...)
      if (length(balance) == 0) balance <<- 0
      invisible(.self)
    },
    deposit = function(x) balance <<- balance + x,
    deposit_twice = function(x) {
      deposit(x)
      deposit(x)
    }
  )
))
a <- Account$new(owner = "Ada")
a$deposit_twice(10)
print(a$balance)

Sortie :

[1] 20

À l’intérieur d’une méthode, un <- simple appliqué à un nom de champ crée une variable locale portant ce nom et laisse le champ inchangé. Utilisez <<- pour chaque modification d’un champ :

Counter <- suppressMessages(setRefClass("Counter",
  fields = list(count = "numeric"),
  methods = list(
    broken = function() count <- count + 1,
    working = function() count <<- count + 1
  )
))
c1 <- Counter$new(count = 0)
c1$broken()
c1$broken()
c1$working()
print(c1$count)

Sortie :

[1] 1
challenge icon

Défi

Facile

Complétez la classe de référence Stack dans Stack.R. Elle conserve ses éléments dans le champ items (caractères, le dernier élément étant au sommet) et possède quatre méthodes :

  • push(x) ajoute x au sommet et renvoie invisible(.self), afin de permettre l’enchaînement des appels ;
  • pop() supprime et renvoie l’élément au sommet, ou renvoie nothing lorsque la pile est vide ;
  • peek() renvoie l’élément au sommet sans le supprimer, ou nothing ;
  • size() renvoie le nombre d’éléments.

La définition est déjà enveloppée dans suppressMessages(). Le code fourni lit les commandes push a b, pop et peek, puis ajoute deux éléments supplémentaires en un seul appel enchaîné et affiche la taille.

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

Essayez vous-même

source("Stack.R")

# Code d'entrée/sortie fourni : le garder tel quel
input <- suppressWarnings(readLines(file("stdin")))
s <- Stack$new()
for (cmd in input) {
  if (startsWith(cmd, "push ")) {
    items <- strsplit(substring(cmd, 6), " ")[[1]]
    for (it in items) s$push(it)
  } else if (cmd == "pop") {
    cat("popped ", s$pop(), "\n", sep = "")
  } else if (cmd == "peek") {
    cat("top ", s$peek(), "\n", sep = "")
  }
}
s$push("x")$push("y")
cat("size after two chained pushes: ", s$size(), "\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