Menu
Coddy logo textTech

Notions de base sur NextMethod

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

À l’intérieur d’une méthode, NextMethod() appelle la méthode suivante pour le même générique, avec les mêmes arguments. Pour un objet possédant une seule classe, la méthode suivante est la méthode par défaut ; une méthode peut donc réutiliser la réponse générale et y ajouter des éléments :

describe <- function(x) UseMethod("describe")
describe.default <- function(x) paste("an object with", length(x), "fields")
describe.task <- function(x) paste0(NextMethod(), ", titled ", x$title)
t <- structure(list(title = "Buy milk", done = FALSE), class = "task")
print(describe(t))

Sortie :

[1] "an object with 2 fields, titled Buy milk"

Un objet peut avoir plusieurs classes dans un vecteur, comme c("urgent", "task"). La répartition essaie ces classes dans l’ordre, et NextMethod() dans la première méthode passe à la méthode correspondant à la classe suivante :

describe <- function(x) UseMethod("describe")
describe.task <- function(x) paste("task:", x$title)
describe.urgent <- function(x) paste("URGENT", NextMethod())
fix <- structure(list(title = "Fix the leak"), class = c("urgent", "task"))
print(describe(fix))

Sortie :

[1] "URGENT task: Fix the leak"

NextMethod() transmet chaque argument reçu par la méthode, y compris ceux supplémentaires tels que sep. La méthode suivante voit les mêmes valeurs sans que vous ayez à les énumérer à nouveau :

label <- function(x, sep = ": ") UseMethod("label")
label.default <- function(x, sep = ": ") paste0("item", sep, x$name)
label.box <- function(x, sep = ": ") paste0("[", NextMethod(), "]")
b <- structure(list(name = "tools"), class = "box")
print(label(b))
print(label(b, sep = " = "))

Résultat :

[1] "[item: tools]"
[1] "[item = tools]"

Base R utilise NextMethod() pour conserver une classe lorsqu’un vecteur est indexé. Le [ par défaut supprime la classe, donc une méthode "[.percent" lui permet d’effectuer le travail et de restaurer la classe :

format.percent <- function(x, ...) paste0(unclass(x) * 100, "%")
"[.percent" <- function(x, i) structure(NextMethod(), class = "percent")
p <- structure(c(0.1, 0.25, 0.5), class = "percent")
print(format(p[2:3]))

Sortie :

[1] "25%" "50%"
challenge icon

Défi

Facile

Les tâches et les tâches urgentes sont deux classes réparties dans deux fichiers. Dans Task.R, complétez la méthode générique describe(), la méthode par défaut, qui renvoie an item, ainsi que describe.task(), qui renvoie an item: Buy milk en appelant NextMethod() et en ajoutant le titre. Dans Urgent.R, complétez describe.urgent(), qui renvoie URGENT an item: Fix bug en appelant NextMethod().

Les constructeurs sont fournis : une tâche urgente possède la classe c("urgent", "task"). Le code fourni lit les lignes task Buy milk, urgent Fix bug ou tout autre mot accompagné d’un titre, qui devient un objet de cette classe, puis affiche describe() pour chacun.

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

Essayez vous-même

source("Task.R")
source("Urgent.R")

# Code d'entrée/sortie fourni : le garder tel quel
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  kind <- sub(" .*", "", line)
  title <- sub("^[a-z]+ ", "", line)
  t <- if (kind == "urgent") new_urgent(title) else if (kind == "task") new_task(title) else structure(list(title = title), class = kind)
  cat(describe(t), "\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