Si un objet marche comme un canard…
J’interroge aujourd’hui monsieur Java et monsieur Ruby afin de connaître leur position par rapport aux types d’objets.
Monsieur Java
Ce n’est pas compliqué. A ce niveau, les classes se comportent comme les types primitifs tels int, string ou float. Si je créé une instance de la classe Legumineuse, cela deviendra son type. L’objet vivra et mourra avec cette étiquette.
Monsieur Ruby
Un instant! Je ne crois pas qu’une classe soit un type. Selon moi, un objet doit être jugé sur ce qu’il peut faire et non sur l’étiquette collé sur lui. Si l’objet marche et parle comme un canard, c’est un canard!
Monsieur Java
Avez-vous consommé des substances illicites mon ami? Cessez de divaguer avec vos canards! Avec votre philosophie de hippie, comment faites-vous pour empêcher les exceptions au niveau des types ?
Monsieur Ruby
Je crois que ces erreurs arrivent moins souvent qu’on le prétend. Je vais citer une phrase du livre Programming Ruby (communément appelé the pickaxe book) afin d’expliquer mon point :
[…] If you coded in Java (pre Java 1.5), all your containers were effectively untyped: everything in a container was just an Object, and you cast it to the required type when you extracted an element. And yet you probably never saw a ClassCastException when you ran these programs. The structure of the code just didn’t permit it : you put Person objects in, and you later took Person objects out. You just don’t write programs that would work in another way. […]
Mon langage permet tout de même de vérifier si un objet marche et parle comme un canard. Plutôt que d’avoir une instruction typeof comme dans ton langage, la classe Object a une méthode du nom de respond_to.
Par exemple, je pourrais faire :
unless anObjet.respond_to?(:some_function)
…fail TypeError.new(”anObject needs someFunction capability”)
end
Mais je suis prudent quant à l’usage de cette pratique. Il faut se demander s’il y a un réel avantage à faire cela. Si nous sommes pour lever une exception manuellement de toute façon, pourquoi ne pas laisser Ruby le faire par lui-même quand le moment sera venu?
Monsieur Java
Vraiment, Ruby n’est pas un langage sérieux.
Monsieur Ruby
Laisses-moi te prouver que juger les objets selon ce qu’ils peuvent faire (ducktyping) peut être avantageux :
class Customer
…def initialize(first_name, last_name)
……@first_name = first_name
……@last_name = last_name
…end
…def append_name_to_file(file)
……file << @first_name << " " << @last_name
...end
end
Si j'effectue des tests sur cette fonction mais que je ne souhaite pas avoir à faire tout le travail pour créer un fichier et le réouvrir afin de m'assurer que la chaîne de caractère a été ajoutée correctement, rien ne m'empêche d'utiliser autre chose qu'un objet File. Tout ce dont j'ai besoin, c'est un objet qui marche comme un fichier et qui parle comme un fichier. Dans le présent cas, je n'ai besoin que d'un objet qui implémente la méthode << (append)
String est un sujet idéal :
def TestSomething
… c = Customer.new(”Radek”, “Bonk”)
…str = “”
…c.append_name_to_file(str)
end
Monsieur Java
Je ne t’aime pas
Monsieur Ruby
Moi non plus
Cela complète l’entretien, merci messieurs!