Champ type et =?iso-8859-15?q?red=E9finition_objet?=

Bonjour,

Je viens de constater quelquechose d’assez suprennant. J’ai un champ de
ma table en base qui porte le nom type. Lorsque j’appelle cette méthode
sur mon modèle, j’ai le warning suivant :

script/../config/../app/views/networks/show.rhtml:5: warning:

Object#type is deprecated; use Object#class

et le résultat obtenu est la classe de mon modèle et non la valeur du
champ en base…

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.

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) ?

Pourquoi ce n’est pas similaire à la méthode id, dépréciée également au
niveau Ruby et remplacée par object_id ?

Merci pour vos lumières,

Julien

Julien :

Je viens de constater quelquechose d’assez suprennant. J’ai
un champ de ma table en base qui porte le nom type. Lorsque
j’appelle cette méthode sur mon modèle, j’ai le warning suivant :

script/../config/../app/views/networks/show.rhtml:5: warning:

Object#type is deprecated; use Object#class

et le résultat obtenu est la classe de mon modèle et non la valeur du
champ en base…

Oui, il ne faut pas utiliser ‘type’ comme nom de méthode ou
de colonne.

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.

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.

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)

РJean-Fran̤ois.

Julien :

Je viens de constater quelquechose d’assez suprennant. J’ai un
champ de ma table en base qui porte le nom type. Lorsque j’appelle
cette méthode sur mon modèle, j’ai le warning suivant :

script/../config/../app/views/networks/show.rhtml:5: warning:

Object#type is deprecated; use Object#class

ah, j’oubliais, dans 1.9.1, Object#type sera supprimé.
Donc d’ici-là … (et faudrait que Ruby on Rails marche sur 1.9.1)

Et ‘type’ est le nom de colonne utilisé pour le Single Table Inheritance
(STI) dans AR.

РJean-Fran̤ois.

Jean-François wrote:

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 ? :slight_smile:

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 :slight_smile:

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 ?

Merci pour tes réponses.

Jean-François wrote:

Et ‘type’ est le nom de colonne utilisé pour le Single Table Inheritance
(STI) dans AR.
exact… encore une question de newbie (pfff) …

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 ? :slight_smile:

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 :slight_smile:

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 :slight_smile:

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.

Jean-François wrote:

Ton receveur, soit il sait traiter ce message, car c’est une
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.

J’ai lu le chapitre à ce sujet dans Programming Ruby (celui avec les
jolis schémas), il y a un petit moment, sans tout comprendre
toutefois… Ton explication (même partielle) me paraît plus claire,
merci donc :slight_smile:

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.

Ok :slight_smile:

C’est une question de vocabulaire :slight_smile: mais pour moi la redéfinition est
la définition dans une classe fille d’une méthode définie plus haut dans
la hiérarchie avec exactement la même signature.
La surcharge, quant à elle, est la définition au même niveau
hiérarchique d’une méthode ayant le même nom mais un prototype
différent. Mais c’est vrai aussi qu’en Ruby on peut définir au même
niveau hiérarchique une méthode ayant exactement la même signature…