Typage canard
Fait partie de la section Programmation orientée objet du Journey Ruby de Coddy. Leçon 33 sur 57.
Ruby ne vérifie pas la classe d'un objet avant d'appeler une méthode : il lui suffit que l'objet possède cette méthode. « S'il marche comme un canard et cancane comme un canard, c'est un canard. » C'est le duck typing : des classes qui ne partagent aucune superclasse peuvent tout de même être utilisées au même endroit :
class Duck
def speak
"Quack"
end
end
class Robot
def speak
"Beep"
end
end
class Radio
def speak
"...news..."
end
end
[Duck.new, Robot.new, Radio.new].each { |thing| puts thing.speak }Sortie :
Quack
Beep
...news...Les classes intégrées participent également. Une méthode qui utilise uniquement << fonctionne avec un tableau, une chaîne ou n’importe quel objet à vous qui définit << :
class Tally
attr_reader :count
def initialize
@count = 0
end
def <<(_item)
@count += 1
self
end
end
def export(items, target)
items.each { |item| target << item.to_s }
target
end
p export([1, 2], [])
p export([1, 2], +"")
puts export([1, 2, 3], Tally.new).countSortie :
["1", "2"]
"12"
3respond_to?(:name) vérifie si un objet possède une méthode publique, sans l’appeler. Utilisez-le lorsqu’un objet peut prendre en charge, ou non, une fonctionnalité facultative :
class Printer
def print_page(text)
"printing #{text}"
end
end
class Scanner
end
[Printer.new, Scanner.new].each do |device|
if device.respond_to?(:print_page)
puts device.print_page("report")
else
puts "#{device.class} cannot print"
end
endSortie :
printing report
Scanner cannot printLorsque l’objet ne possède pas la méthode, l’appel lève NoMethodError, dont le message indique la méthode et l’objet. Le typage canard repose sur le fait que chaque objet transmis réponde aux méthodes qui lui sont envoyées :
def loudest(things)
things.map(&:speak).max_by(&:size)
end
class Cat
def speak
"Meow"
end
end
puts loudest([Cat.new, Cat.new])
begin
loudest([Cat.new, 42])
rescue NoMethodError => e
puts e.message
endSortie :
Meow
undefined method `speak' for an instance of IntegerDéfi
FacileComplétez les classes Printer et LineCounter ainsi que la fonction auxiliaire export(items, target) dans functions.rb. export envoie chaque élément vers la cible avec target << item.to_s et renvoie la cible. Printer#<< affiche le texte avec un numéro de ligne, 1: text, et renvoie l’imprimante. LineCounter#<< compte les lignes et les caractères et renvoie le compteur ; son to_s renvoie 3 lines, 12 chars.
Le code fourni lit les éléments, les exporte vers un tableau (affiché avec p), vers une nouvelle chaîne (affichée avec p), vers un Printer et vers un LineCounter (affiché avec puts).
Votre code doit être placé dans printer.rb, line_counter.rb et functions.rb. main.rb contient le code d’entrée/sortie fourni et ne peut pas être modifié.
Essayez vous-même
require_relative 'printer'
require_relative 'line_counter'
require_relative 'functions'
# Code d'entrée/sortie fourni : le garder tel quel
input = []
while (line = gets)
input << line.chomp
end
p export(input, [])
p export(input, +"")
export(input, Printer.new)
puts export(input, LineCounter.new)
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
1Classes et objets
Travailler avec des fichiersDéfinir des classesVariables d’instanceMéthodes et selfto_s et inspectRécapitulatif - Carte de bibliothèque4Encapsulation
Méthodes privéesMéthodes protégéesSetters privésProtéger l’étatRécapitulatif - Distributeur automatique7Polymorphisme et typage canard
PolymorphismeTypage canardMéthodes abstraitesCas et classesRécapitulatif - méthodes de paiement10Patrons de conception – Partie 2
Délégation avec ForwardablePatron DécorateurPatron BuilderPatron État2Accesseurs et self
Lecteurs et écrivainsSetters personnalisésself dans les méthodesIdentité et égalitéRécapitulatif - Liste de contacts5Héritage
Sous-classesRedéfinition des méthodesAppeler superis_a? et ancêtresRécapitulatif - Paie du personnel8Méthodes spéciales
Égalité et hachageMéthodes d’opérateursIndexation et ajoutCollections personnaliséesRécapitulatif - Fractions11Projet : Gestion de bibliothèque
Livres et membresEmprunter des livresEntraînez-vous par vous-même : Compilateur Ruby en ligne