Que signifie la carte(&:nom) signifie en Ruby?
J'ai trouvé ce code dans un RailsCast:
def tag_names
@tag_names || tags.map(&:name).join(' ')
end
Ce qui ne l' (&:name)
dans map(&:name)
veux dire?
- J'ai entendu ce qu'on appelle “bretzel du côlon”, par la manière.
- Haha. Je sais que comme une Esperluette. Je n'ai jamais entendu qu'il appelle un "bretzel", mais qui fait sens.
- Vous pouvez également déposer les fixations
tags.map &:name
pour le plus court de l'entrée. - En l'appelant "bretzel colon" est trompeur, bien que accrocheur. Il n'y a pas de "&:" en ruby. L'esperluette (&) est un "unaire et commercial de l'opérateur" avec une poussée :symbole. Si quoi que ce soit, c'est un "bretzel symbole". Juste pour dire.
- les balises.carte(&:nom) est une sorte de de tags.carte{|s| s.nom}
- "bretzel colon" sonne comme un problème de santé pénible... mais j'aime bien le nom de ce symbole 🙂
- brianstorti.com/understanding-ruby-idiom-map-with-symbol
Vous devez vous connecter pour publier un commentaire.
C'est un raccourci pour
tags.map(&:name.to_proc).join(' ')
Si
foo
est un objet avec uneto_proc
méthode, alors vous pouvez passer à une méthode comme&foo
, qui feront appelfoo.to_proc
et de l'utiliser comme méthode de blocage.La
Symbol#to_proc
méthode a été initialement ajouté par ActiveSupport mais a été intégré dans Ruby 1.8.7. C'est sa mise en œuvre:&
, j'.etags.map(&:name.to_proc).join(' ')
tags.map(&:name).join(' ')
sansto_proc
tags.map { |tag| tag.name }
est effectivement ce quetags.map(&:name.to_proc)
n', il n'est pas exactement la sténographie, en soi. C'est parce que les procs peuvent être converties en blocs, en utilisant le & opérateur de, quand ils sont passés aux méthodes qui utilisent le rendement et nécessitent donc un bloc. (Voir la documentation de Ruby ici). Comme Josh Lee a montré dans son post ci-dessus, les symboles peuvent également être convertis à un procs et, à partir de là, peut ensuite être convertie en un bloc, ce qui est nécessaire parce que la carte utilise des blocs.#__send__
au lieu de#send
à elle est plus sécuritaire. Un objet peut remplacersend
pour une raison quelconque (par exemple. l'envoi d'e-mails), mais si vous faites la même chose avec#__send__
, Ruby VM lance un avertissement.If foo is an object with a to_proc method, then you can pass it to a method as &foo
. Veuillez illustrer avec un exemple, c'est beaucoup trop abstrait pour moi. Qu'est-ce que&foo
construction du langage même appelé? Ne sais pas quoi google afin de rendre cela plus clair.Un autre cool abréviation, inconnu pour beaucoup, est
qui est une abréviation pour
En appelant
method(:foo)
nous avons pris unMethod
objet deself
qui représente safoo
méthode, et a utilisé le&
pour signifier qu'il a unto_proc
méthode qui le convertit en unProc
.Cela est très utile lorsque vous voulez faire les choses point-gratuit style. Un exemple est de vérifier s'il existe une chaîne dans un tableau qui est égal à la chaîne
"foo"
. Il y a la méthode classique:Et il est le point moyen:
Le moyen préféré doit être le plus lisible un.
array.each{|e| foo(e)}
est plus courte encore 🙂 +1 de toute façon&method
?[1,2,3].map(&Array.method(:new))
C'est l'équivalent de
Tout en notons aussi que les esperluette
#to_proc
la magie peut travailler avec n'importe quelle classe, et pas seulement un Symbole. De nombreux Rubyists choisir de définir#to_proc
sur la classe Array:Esperluette
&
fonctionne en envoyantto_proc
message sur son opérande, qui, dans le code ci-dessus, est de la classe Array. Et depuis que j'ai défini#to_proc
méthode sur le Tableau, la ligne devient:C'est un raccourci pour
tags.map { |tag| tag.name }.join(' ')
&
opérateur appelsto_proc
sur son opérande. Il n'est donc pas spécifique à la méthode map, et travaille en fait sur une méthode qui prend un bloc et passe un ou plusieurs arguments pour le bloc.est Le même que
&:name
utilise juste le symbole comme le nom de la méthode appelée.Josh Lee réponse est presque correct, sauf que l'équivalent du code Ruby doit avoir été comme suit.
pas
Avec ce code, lorsque
print [[1,'a'],[2,'b'],[3,'c']].map(&:first)
est exécutée, Ruby divise la première entrée[1,'a']
en 1 et " un " pour donner deobj
1 etargs*
de 'a' à cause d'une erreur que Fixnum objet 1 ne dispose pas de la méthode de l'auto (qui est :d'abord).Quand
[[1,'a'],[2,'b'],[3,'c']].map(&:first)
est exécutée;:first
est un Symbole de l'objet, de sorte que lorsque&:first
est donné à une méthode map en tant que paramètre, Symbole#to_proc est invoquée.carte envoie message d'appel à :premier.to_proc avec le paramètre
[1,'a']
, par exemple,:first.to_proc.call([1,'a'])
est exécutée.to_proc procédure dans le Symbole de la classe envoie envoyer un message à un objet array (
[1,'a']
) avec le paramètre (:d'abord), par exemple,[1,'a'].send(:first)
est exécutée.itère sur le reste des éléments dans
[[1,'a'],[2,'b'],[3,'c']]
objet.C'est la même que l'exécution de
[[1,'a'],[2,'b'],[3,'c']].map(|e| e.first)
expression.[1,2,3,4,5,6].inject(&:+)
- injecter attend un lambda avec deux paramètres (memo et de l'item) et:+.to_proc
livre -Proc.new |obj, *args| { obj.send(self, *args) }
ou{ |m, o| m.+(o) }
Deux il se passe des choses ici, et il est important de comprendre à la fois.
Comme décrit dans les autres réponses, le
Symbol#to_proc
méthode est appelée.Mais la raison
to_proc
est appelée sur le symbole, parce que c'est passé àmap
comme un bloc argument. Placer&
en face d'un argument lors de l'appel de méthode causes qu'il soit passé de cette façon. Cela est vrai pour toute méthode Ruby, pas seulementmap
avec des symboles.La
Symbol
est converti enProc
parce qu'il est transmis sous la forme d'un bloc. On peut montrer cela en essayant de faire passer un proc à.map
sans l'esperluette:Même si elle n'a pas besoin d'être converti, la méthode ne savent pas comment l'utiliser car il s'attend à un bloc argument. En passant dessus avec
&
donne.map
le bloc qu'il attend.(&:nom) est l'abréviation de (&:nom.to_proc) c'est la même que
tags.map{ |t| t.name }.join(' ')
to_proc est réellement mis en œuvre en C
Bien que nous avons beaucoup de réponses déjà, en regardant à travers un point de vue de débutant, je tiens à ajouter les informations supplémentaires suivantes:
Cela signifie, que vous êtes de passage à une autre méthode en paramètre à la fonction map.
(En réalité, vous êtes le passage d'un symbole qui est converti en un proc. Mais ce n'est pas important dans ce cas particulier).
Ce qui est important, c'est que vous avez un
method
nomméname
qui sera utilisé par la méthode map comme argument au lieu de la traditionnelleblock
style.carte(&:nom) prend un objet énumérable (balises dans votre cas) et exécute le nom de la méthode pour chaque élément/tag, sortie de chaque valeur retournée par la méthode.
C'est un raccourci pour
qui renvoie la matrice de l'élément(balise) les noms
Ici
:name
est le symbole du point de la méthodename
de la balise object.Quand on passe
&:name
àmap
, elle traitera dename
comme un proc objet.Pour faire court,
tags.map(&:name)
actes comme:cela signifie
Fondamentalement exécuter l'appel de la méthode
tag.name
sur chacune des étiquettes dans le tableau.C'est une forme simplifiée de rubis de sténographie.
C'est la même que ci-dessous: