J'ai trouvé ce code dans un RailsCast :
def tag_names
@tag_names || tags.map(&:name).join(' ')
end
Que fait le (&:name)
en map(&:name)
C'est-à-dire ?
J'ai trouvé ce code dans un RailsCast :
def tag_names
@tag_names || tags.map(&:name).join(' ')
end
Que fait le (&:name)
en map(&:name)
C'est-à-dire ?
C'est un raccourci pour tags.map(&:name.to_proc).join(' ')
Si foo
est un objet avec un to_proc
vous pouvez alors le passer à une méthode en tant que &foo
qui appellera foo.to_proc
et l'utiliser comme bloc de la méthode.
Le site Symbol#to_proc
a été ajoutée à l'origine par ActiveSupport mais a été intégrée dans Ruby 1.8.7. Voici son implémentation :
class Symbol
def to_proc
Proc.new do |obj, *args|
obj.send self, *args
end
end
end
Ce n'est pas du code ruby valide, vous avez toujours besoin de l'option &
c'est-à-dire tags.map(&:name.to_proc).join(' ')
Un autre raccourci cool, inconnu de beaucoup, est
array.each(&method(:foo))
qui est un raccourci pour
array.each { |element| foo(element) }
En appelant method(:foo)
nous avons pris un Method
l'objet de self
qui représente son foo
et a utilisé la méthode &
pour signifier qu'il a un to_proc
méthode qui le convertit en un Proc
.
C'est très utile lorsque vous voulez faire des choses sans point le style. Un exemple est de vérifier s'il y a une chaîne dans un tableau qui est égale à la chaîne "foo"
. Il y a la voie conventionnelle :
["bar", "baz", "foo"].any? { |str| str == "foo" }
Et il y a la voie sans points :
["bar", "baz", "foo"].any?(&"foo".method(:==))
La méthode privilégiée doit être la plus lisible.
Notons également que l'esperluette #to_proc
La magie peut fonctionner avec n'importe quelle classe, pas seulement avec la Symbole. De nombreux Rubyistes choisissent de définir #to_proc
sur la classe Array :
class Array
def to_proc
proc { |receiver| receiver.send *self }
end
end
# And then...
[ 'Hello', 'Goodbye' ].map &[ :+, ' world!' ]
#=> ["Hello world!", "Goodbye world!"]
Ampersand &
fonctionne en envoyant to_proc
sur son opérande, qui, dans le code ci-dessus, est de la classe Array. Et comme j'ai défini #to_proc
sur Array, la ligne devient :
[ 'Hello', 'Goodbye' ].map { |receiver| receiver.send( :+, ' world!' ) }
Est-ce un simple idiome pour map ou Ruby interprète-t-il toujours le "&" d'une manière particulière ?
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
133 votes
J'ai entendu dire que cela s'appelait "colon bretzel", d'ailleurs.
6 votes
Haha. Je connais ça comme une esperluette. Je n'ai jamais entendu dire que c'était un "bretzel", mais c'est logique.
1 votes
Vous pouvez également supprimer les crochets
tags.map &:name
pour l'entrée la plus courte.76 votes
L'appeler "bretzel colon" est trompeur, bien qu'accrocheur. Il n'y a pas de "& :" en rubis. L'esperluette (&) est un "opérateur d'esperluette unaire" avec un symbole :poussé ensemble. En fait, c'est un "symbole bretzel". Je dis ça comme ça.
3 votes
Tags.map(&:name) est trié à partir de tags.map{|s| s.name}
4 votes
"Pretzel colon" sonne comme une condition médicale douloureuse... mais j'aime le nom de ce symbole :)
0 votes
brianstorti.com/comprendre-ruby-idiom-map-with-symbol