64

Possible Duplicate:
What does map(&:name) mean in Ruby?

I came across a code snippet which had the following

a.each_slice(2).map(&:reverse)

I do not know the functionality of &: operator. How does that work?

Community
  • 1
  • 1
Rahul
  • 42,073
  • 24
  • 68
  • 100
  • 2
    This is a duplicate of no less than 17 other questions that have already been asked and answered here on StackOverflow: [Understanding \[ClassOne, ClassTwo\].each\(&:my_method\)](http://StackOverflow.Com/q/99318/), [What does `map(&:name)` mean in Ruby?](http://StackOverflow.Com/q/1217088/), [What exactly is `&:capitalize` in Ruby?](http://StackOverflow.Com/q/1792683/), [Ruby/Ruby on Rails ampersand colon shortcut](http://StackOverflow.Com/q/1961030/), [Ruby : `&:symbol` syntax](http://StackOverflow.Com/q/2096975/), … – Jörg W Mittag Feb 24 '12 at 15:27
  • 2
    … [What is this `&:last` Ruby Construct Called?](http://StackOverflow.Com/q/2211751/), [What do you call the `&:` operator in Ruby?](http://StackOverflow.Com/q/2259775/), [What does `map(&:name)` do in this Ruby code?](http://StackOverflow.Com/q/2388337/), [What are `:+` and `&+` in ruby?](http://StackOverflow.Com/q/2697024/), [`&:views_count` in `Post.published.collect(&:views_count)`](http://StackOverflow.Com/q/3888044/), [Ruby Proc Syntax](http://StackOverflow.Com/q/4512587/), [How does “`(1..4).inject(&:+)`” work in Ruby](http://StackOverflow.Com/q/5003257/), … – Jörg W Mittag Feb 24 '12 at 15:27
  • 2
    … [What does following statement `&:property` ?](http://StackOverflow.Com/q/5620411/), [What does the `&` mean in the following ruby syntax?](http://StackOverflow.Com/q/5952175/), [Why would one use the unary operator on a property in ruby? i.e `&:first`](http://StackOverflow.Com/q/6289084/), [how does `Array#map` have parameter to do something like this?](http://StackOverflow.Com/q/6716629/), and [what does `&:` mean in ruby, is it a block mixed with a symbol?](http://StackOverflow.Com/q/9188362/). – Jörg W Mittag Feb 24 '12 at 15:27

2 Answers2

112

There isn't a &: operator in Ruby. What you are seeing is the & operator applied to a :symbol.

In a method argument list, the & operator takes its operand, converts it to a Proc object if it isn't already (by calling to_proc on it) and passes it to the method as if a block had been used.

my_proc = Proc.new { puts "foo" }

my_method_call(&my_proc) # is identical to:
my_method_call { puts "foo" }

So the question now becomes "What does Symbol#to_proc do?", and that's easy to see in the Rails documentation:

Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:

# The same as people.collect { |p| p.name }
people.collect(&:name)

# The same as people.select { |p| p.manager? }.collect { |p| p.salary }
people.select(&:manager?).collect(&:salary)
Gareth
  • 124,675
  • 36
  • 145
  • 155
  • 4
    You are implying it, but it would be better to tell it explicitly: this is a modification that Rails does, and it's not built-in in Ruby itself. – kikito Feb 24 '12 at 11:30
  • 7
    @kikito: http://ruby-doc.org/core-1.9.3/Symbol.html#method-i-to_proc – tokland Feb 24 '12 at 11:37
  • 1
    You are right - I've just tried it in plain irb (1.8.7), it's in Ruby itself. This one is not provided by Rails. Thanks for correcting my error! – kikito Feb 24 '12 at 11:45
  • 5
    @kikito: actually it was first implemented in Rails, but everyone loved it so it made its way into the core. – tokland Feb 24 '12 at 12:05
  • 1
    Please don't answer duplicate questions. Just vote to close. This question was already asked and answered 17(!!!) times, there really is *nothing* gained by spreading out the knowledge even more. – Jörg W Mittag Feb 24 '12 at 15:30
  • Is there a way to pass and argument to the method being called? `salary` for example – Deekor Feb 01 '16 at 22:03
37

By prepending & to a symbol you are creating a lambda function that will call method with a name of that symbol on the object you pass into this function. Taking that into account:

ar.map(&:reverse)

is roughly equivalent to:

ar.map { |element| element.reverse }
KL-7
  • 43,332
  • 9
  • 85
  • 74