[Ruby on Rails] La délégation des méthodes - Version imprimable +- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org) +-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38) +--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51) +--- Sujet : [Ruby on Rails] La délégation des méthodes (/showthread.php?tid=4398) |
[Ruby on Rails] La délégation des méthodes - Sephi-Chan - 10-10-2009 La délégation des méthodes ActiveSupport intègre un composant bien sympathique à la classe Module : la méthode delegate. Cette méthode permet, comme son nom l'indique, de déléguer son travail à une autre méthode. Le cas d'exemple est un jeu (Bugspirit) découpé en parties (les univers) pouvant accueillir un certain nombre de groupes de joueurs (les nuées). Ce nombre de groupe est déterminé par la carte associée à l'univers. Une petite carte pourra accueillir un nombre restreint de groupe qu'une carte immense. Et c'est là qu'entre en jeu le délégué : quand on demandera le nombre de joueurs qu'un univers peut accueillir, il ira demander cette information à sa carte. Voici donc une partie de la classe Universe (très épurée, pour se focaliser sur l'exemple) :
On précise que notre univers est associé à une carte grâce à une relation belongs_to :map (Map étant un autre modèle). Notre table universes contient une colonne map_id. Cette ligne ajoute (entre autre) à nos instances de la classe Universe une méthode map qui va chercher la carte associé à l'univers dans la base de données. Grâce à la ligne delegate :maximum_number_of_swarms, :to => :map, on demande à nos instance de la classe Universe de répondre à la méthode maximum_number_of_swarms en appelant à son tour cette méthode sur l'objet map et en retournant le résultat. Ainsi, les codes qui suivent sont équivalents :
Dans notre cas, à chaque fois qu'on ajoutera un nuée (Swarm) aux nuées associées à cet univers, le callback after_add sera appelé et vérifiera si — en comptant la nuée ajoutée — l'univers a accueilli le nombre maximal de groupes permis par la carte. Si c'est le cas, le flag qui indique si la partie est pleine, ce qui par ailleurs conduira au lancement de la partie grâce au callback after_update tart_the_game, :if => :full_changed?. Notez que les méthodes délégués peuvent être délégués à des variables de classes, d'instance ou des constantes appartenant elle-mêmes à la classe en cours ou autre.
On peut également préfixer la méthode. Ainsi, si je veux connaître l'adresse de livraison d'une commande (qui est en fait l'adresse de la personne qui a commandé), appelée @order.person_address a plus de sens que d'appeller @order.address.
Notez que le préfixe peut être donné explicitement, ainsi, plutôt que de parler de l'adresse de la personne, on peut parler de l'adresse d'un client.
On peut aussi déléguer plusieurs méthodes en même temps :
Enfin, parlons un peu de la robustesse du code. Souvenez-vous de l'exemple de mon jeu. Quand on appelle la méthode maximum_number_of_swarms, elle est en fait appelée sur la carte associée à l'univers. Si cette carte n'existe pas, Ruby cherchera à appeler la méthode sur un objet inexistant (nil, puisque c'est ce que renverra la méthode map si l'univers n'a pas de carte) ! Pour éviter cela, on peut procéder à une petite modification :
Ainsi, si on vient à demander le nombre de nuées que peut accueillir un univers alors que celui-ci n'a pas de carte associée, alors il se contentera simplement de répondre nil. Voilà pour les délégués ! Si ce sujet vous a intéressé — que Ruby vous tente ou non — je vous serais reconnaissant de me donner votre ressenti afin que je puisse l'améliorer. Sephi-Chan, qui ne pensait pas en écrire autant quand il a commencé… |