37

Possible Duplicates:
Ruby/Ruby on Rails ampersand colon shortcut
What does map(&:name) mean in Ruby?

I was reading Stackoverflow and stumbled upon the following code

array.map(&:to_i)

Ok, it's easy to see what this code does but I'd like to know more about &: construct which I have never seen before.

Unfortunately all I can think of is "lambda" which it is not. Google tells me that lambda syntax in Ruby is ->->(x,y){ x * y }

So anyone knows what that mysterious &: is and what it can do except calling a single method?

Community
  • 1
  • 1
vava
  • 24,851
  • 11
  • 64
  • 79
  • 11
    This is an exact duplicate of *six* different questions. And believe me, Ruby hasn't changed *that* much within the last 8 days, so the answers are *probably* going to be the same: 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/. – Jörg W Mittag Feb 14 '10 at 10:19
  • 7
    Sure, I know this now. But every new way of wording will help the community and this site. After all, I *did* search before I asked. – vava Feb 14 '10 at 11:18
  • 4
    @vava That is a reason *not to delete* the question. Your question should still be closed. – Sinan Ünür Feb 14 '10 at 21:32
  • 1
    @Sinan, by closing it, you made it invisible to Google and it will lead to another question like that popping up :) – vava Feb 15 '10 at 01:20
  • @vava http://www.google.com/search?q=What+do+you+call+the+%26%3A+operator+in+Ruby%3F See also http://meta.stackexchange.com/questions/230/duplicate-question-etiquette-to-delete-or-not-to-delete – Sinan Ünür Feb 15 '10 at 01:34
  • @Sinan, ok, I stand corrected. – vava Feb 15 '10 at 03:41
  • @AJP That's also how I got here. Every programmer should be using it. – Gerry Jul 31 '13 at 17:21

1 Answers1

70

There's a few moving pieces here, but the name for what's going on is the Symbol#to_proc conversion. This is part of Ruby 1.9 and up, and is also available if you use later-ish versions of Rails.

First, in Ruby, :foo means "the symbol foo", so it's actually two separate operators you're looking at, not one big &: operator.

When you say foo.map(&bar), you're telling Ruby, "send a message to the foo object to invoke the map method, with a block I already defined called bar". If bar is not already a Proc object, Ruby will try to make it one.

Here, we don't actually pass a block, but instead a symbol called bar. Because we have an implicit to_proc conversion available on Symbol, Ruby sees that and uses it. It turns out that this conversion looks like this:

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

This makes a proc which invokes the method with the same name as the symbol. Putting it all together, using your original example:

array.map(&:to_i)

This invokes .map on array, and for each element in the array, returns the result of calling to_i on that element.

Dhanu Gurung
  • 8,480
  • 10
  • 47
  • 60
John Feminella
  • 303,634
  • 46
  • 339
  • 357
  • 11
    map(&:to_i) is exactly the same as map { |x| x.to_i }. As map requires block and from ruby 1.9 onwards, Symbol to_proc conversion is implicitly available. – Abhaya Jul 04 '11 at 06:00