2010-02-14 6 views
32

Doublons possibles:
Ruby/Ruby on Rails ampersand colon shortcut
What does map(&:name) mean in Ruby?Comment appelez-vous l'opérateur &: dans Ruby?

je lisais Stackoverflow et sommes tombés sur le code suivant

array.map(&:to_i) 

Ok, il est facile de voir ce que ce code ne mais j'aimerais en savoir plus sur &: construction que je n'ai jamais vu auparavant.

Malheureusement, tout ce que je peux penser est "lambda", ce qui n'est pas le cas. Google me dit que la syntaxe lambda dans Ruby est

Alors quelqu'un sait ce que ce mystérieux &: est et ce qu'il peut faire, sauf appeler une seule méthode?

+10

Ceci est une copie exacte de * six * questions différentes. Et croyez-moi, Ruby n'a pas changé * beaucoup * au cours des 8 derniers jours, donc les réponses sont * probablement * les mêmes: http://StackOverflow.Com/questions/99318/, http: // StackOverflow .Com/questions/1217088 /, http://StackOverflow.Com/questions/1792683/, http://StackOverflow.Com/questions/1961030/, http://StackOverflow.Com/questions/2096975/, http://StackOverflow.Com/questions/2211751/. –

+5

Bien sûr, je le sais maintenant. Mais chaque nouvelle façon de formuler aidera la communauté et ce site. Après tout, j'ai * cherché * avant de demander. – vava

+4

@vava C'est une raison * de ne pas supprimer * la question. Votre question devrait toujours être fermée. –

Répondre

61

Il y a quelques pièces en mouvement ici, mais le nom de ce qui se passe est la conversion Symbol#to_proc. Cela fait partie de Ruby 1.9 et plus, et est également disponible si vous utilisez des versions ultérieures de Rails. En premier lieu, dans Ruby, :foo signifie "le symbole foo", donc c'est en fait deux opérateurs distincts que vous regardez, pas un seul grand opérateur &:.

Quand vous dites foo.map(&bar), vous dites Ruby, « envoyer un message à l'objet foo pour appeler la méthode map, avec un bloc I déjà défini appelé bar ». Si bar n'est pas déjà un objet Proc, Ruby essayera d'en faire un.

Ici, nous ne passons pas réellement un bloc, mais à la place un symbole appelé bar. Parce que nous avons une conversion to_proc implicite disponible sur Symbol, Ruby voit cela et l'utilise. Il se trouve que cette conversion ressemble à ceci:

def to_proc 
    proc { |obj, *args| obj.send(self, *args) } 
end 

Cela fait une proc qui invoque la méthode avec le même nom que le symbole. Mettre tous ensemble, en utilisant votre exemple original:

array.map(&:to_i) 

Cela invoque .map sur la matrice, et pour chaque élément du tableau, renvoie le résultat de l'appel to_i sur cet élément.

+7

map (&: to_i) est exactement la même que la carte {| x | x.to_i}. Comme la carte requiert block et à partir de ruby ​​1.9, la conversion de Symbol to_proc est implicitement disponible. – Abhaya