Julien :
Pour moi, ce n’est pas normal, car on a une redéfinition de
la méthode type au niveau du modèle, modèle qui logiquement
hérite de Object.
Non, car le mécanisme d’AR (via method_missing)
ne fonctionne alors pas.
Peux-tu préciser cela ?
Mmmh c’est un peu long et je vais éviter de rentrer dans les
détails. Je ne vais donc faire comme si l’option
AR::B.generate_read_methods
n’existe pas
Ruby est comme tu le sais, basé sur un système de passage
de message : invoquer une méthode sur un objet, c’est passer
un message à un receveur avec éventuellement des arguments.
Ton receveur, soit il sait traiter ce message, car c’est une
méthode d’instance de sa classe, soit une méthode provenant
de modules mixés dans sa classe, soit une méthode d’instance
de sa classe parente, soit une méthode provenant de modules
mixés dans sa classe parente et ainsi de suite.
Soit il ne sait pas, et si on a défini method_missing,
c’est cette méthode qui va traiter ce message et
agir en conséquence, selon le nom du message par exemple.
Ainsi dans le cas d’AR::B pour accéder à un attribut de
ma table, je passe par une méthode du même nom, et
method_missing va traiter et retourner la bonne valeur.
(je passe vraiment les détails, je suis déjà trop long)
(je parle AR::B#method_missing et non AR::B.method_missing)
Donc comme je disais, comme ton instance de Gabuzomeu < AR::B
a une méthode #type héritée d’Object#type, si tu appelles la
méthode ‘type’, c’est la méthode déjà existante qui va être appelée
et non method_missing, qui ne renverra donc pas la valeur
de ta colonne type.
Quelqu’un peut-il me dire pourquoi j’ai ce comportement, et s’il
y a d’autres méthodes qui peuvent rentrer en conflit (j’imagine
que c’est pareil pour class) ?
tous les noms qui peuvent être des noms de méthodes d’instance
d’ActiveRecord::Base, des classes parentes (Object) et de tous
les modules mixés dans ces classes.
Il faut donc avoir connaissance ce cet ensemble de méthodes,
et/ou faire des tests unitaires
plus on connaît l’API d’AR::B (voire de Rails) et plus on connaît
l’API des classes de base, (et plus on connait stdlib aussi)
mieux on maîtrise le framework oui…
Pourquoi ce n’est pas similaire à la méthode id, dépréciée également
au niveau Ruby et remplacée par object_id ?
Parce que ce n’est pas le même mécanisme (ici surcharge)
Si j’ai bien compris, au niveau AR, on ouvre la classe Object pour
surcharger id ?
La surcharge de méthode, au sens programmation orientée
objet, une méthode définie dans la classe fille sera appelée
en lieu (car plus spécialisé) et place de méthodes du même
nom définies dans les classes parentes. (je passe sur les
modules)
AR::B#id sera utilisé plutôt que Object#id.
Bon, j’ai été trop long.
– Jean-François.