#6 Shortcut Blocks with Symbol to_proc
La syntaxe particulière de la ligne du find
dans le bloc de code suivant, avec le symbole &p;
, est appelée Symbol to_proc
et est quelque chose que Rails apporte à Ruby.
class Project < ActiveRecord::Base has_many :tasks def self.all_names find(:all).collect(&:name) end end
Nous utiliserons le scripts de Rails script/console
pour expliquer comment ça marche. D'abord, allons chercher un tableau de Project
s
Laa-Laa:todo eifion$ script/console Loading development environment (Rails 2.2.2) >> projects = Project.find(:all) => [#<Project id: 1, name: "Write another ASCIIcast", created_at: "2008-12-29 09:32:47", updated_at: "2008-12-29 09:32:47">, #<Project id: 2, name: "Go out walking", created_at: "2008-12-29 09:33:04", updated_at: "2008-12-29 09:33:04">]
Il y a deux projets et nous voulons récupérer un tableau de tous les noms des projets. Une façon de faire serait d'utiliser la méthode collect
, qui prend un bloc, et retourne le name
de chaque Project
. La méthode collect
itère à travers un tableau, exécute un peu de code sur chaque item du tableau, et retourne un tableau contenant chaque résultat du code exécuté sur chaque item du tableau originel.
>> projects.collect { |p| p.name } => ["Write another ASCIIcast", "Go out walking"]
Symbol to_proc
vous permet d'utiliser un raccourci quand vous voulez exécuter une méthode appelée sur l'objet qui est envoyé au bloc. Pour se faire, vous donnez un paramètre qui commence avec l'esperluette (&
) suivi du nom de la méthode en guise de symbole :
>> projects.collect {&:name} => ["Write another ASCIIcast", "Go out walking"]
Ceci devient plus utile quand vous voulez combiner plusieurs appels de méthode :
>> projects.collect(&:name).collect(&:upcase) => ["WRITE ANOTHER ASCIICAST", "GO OUT WALKING"]
Cette technique n'est pas restreinte à la méthode collect
; elle peut être appliquée à n'importe quelle méthode qui prend un bloc comme paramètre. Par exemple, les méthodes any?
et all?
peuvent utiliser ce raccourci pour voir si tout ou partie des projets ou même pour enregistrer tous nos projets.
>> projects.all?(&:valid?) => true >> projects.any?(&:valid?) => true >> projects.each(&:save!) => [#<Project id: 1, name: "Write another ASCIIcast", created_at: "2008-12-29 09:32:47", updated_at: "2008-12-29 09:32:47">, #<Project id: 2, name: "Go out walking", created_at: "2008-12-29 09:33:04", updated_at: "2008-12-29 09:33:04">]
Malgré sa syntaxe légèrement exotique, Symbol to_proc
vaut vraiment la peine d'être utilisée quand vous devez aligner à la chaîne des méthodes avec des blocs.