Menu
Coddy logo textTech

Méthodes par défaut

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

Lorsqu’aucune méthode ne correspond à la classe, UseMethod() recherche la méthode par défaut, name.default. Il s’agit du mécanisme de secours pour toute classe que le générique ne connaît pas :

describe <- function(x) UseMethod("describe")
describe.dog <- function(x) paste("a dog called", x$name)
describe.default <- function(x) "something I do not know"
rex <- structure(list(name = "Rex"), class = "dog")
car <- structure(list(), class = "car")
print(describe(rex))
print(describe(car))

Sortie :

[1] "a dog called Rex"
[1] "something I do not know"

Sans méthode par défaut, l’appel du générique sur une classe inconnue s’arrête avec une erreur :

describe <- function(x) UseMethod("describe")
describe.dog <- function(x) paste("a dog called", x$name)
car <- structure(list(), class = "car")
describe(car)

Sortie :

Error in UseMethod("describe") : 
  no applicable method for 'describe' applied to an object of class "car"
Calls: describe
Execution halted

Les valeurs simples sont également distribuées. Un nombre sans attribut de classe possède la classe implicite numeric, le texte possède character, et TRUE possède logical ; les méthodes portant ces noms fonctionnent donc sur des vecteurs ordinaires :

describe <- function(x) UseMethod("describe")
describe.numeric <- function(x) paste("numbers adding up to", sum(x))
describe.character <- function(x) paste("words:", paste(x, collapse = " "))
describe.default <- function(x) "something else"
print(describe(c(1, 2, 3)))
print(describe(c("a", "b")))
print(describe(TRUE))

Résultat :

[1] "numbers adding up to 6"
[1] "words: a b"
[1] "something else"

Une méthode par défaut peut également refuser poliment : stop() avec un message qui nomme la classe, afin que l’appelant sache ce qui n’a pas fonctionné. class(x)[1] correspond à la première classe de l’objet :

area <- function(shape) UseMethod("area")
area.square <- function(shape) shape$side^2
area.default <- function(shape) {
  stop("cannot compute the area of a ", class(shape)[1], call. = FALSE)
}
for (s in list(structure(list(side = 2), class = "square"), structure(list(), class = "blob"))) {
  cat(tryCatch(area(s), error = function(e) conditionMessage(e)), "\n")
}

Sortie :

4 
cannot compute the area of a blob 
challenge icon

Défi

Facile

Complétez la fonction générique describe(x) dans Describe.R ainsi que ses méthodes pour les vecteurs simples :

  • describe.numeric() renvoie 3 numbers, sum 6.
  • describe.character() renvoie 2 words, longest: apple (le premier des mots les plus longs en cas d’égalité).
  • describe.logical() renvoie 2 of 3 are TRUE.
  • describe.default() renvoie something else.

Le code fourni lit les lignes num 1,2,3, chr apple,kiwi, lgl TRUE,FALSE,TRUE ou tout autre mot accompagné de valeurs, qu’il transforme en liste. Il affiche describe() pour chacune d’elles.

Votre code doit être placé dans Describe.R. main.R contient le code fourni pour les entrées et sorties et ne peut pas être modifié.

Essayez vous-même

source("Describe.R")

# Code d'entrée/sortie fourni : le garder tel quel
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  values <- strsplit(p[2], ",")[[1]]
  x <- switch(p[1],
    num = as.numeric(values),
    chr = values,
    lgl = as.logical(values),
    list(values))
  cat(describe(x), "\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