The symbol.to_proc method was something I hesitated to use for a long time because I found it be unclear and something that went against Ruby’s clear and easy to understand syntax. Though this subject is old news its something I’ve found that goes against ruby’s clarity over cleverness standards.
The Proc Object
A Proc object is block code that can be accessed as an Object. A proc when defined associates itself to a set of variables (local) and can be used at later point of time in the context of those variables
So lets consider a simple example
def test(&block) puts block.class.to_s # "Proc" block.call # would execute the block of code end test{puts "Bazingaaa" } # Bazingaa
So the result would be
"Proc" Bazingaa
Its just a block of code that you can run whenever you want.
Now Ruby symbols have a to_proc method which allows you to convert a symbol to a proc.
:test.methods.include?('to_proc') => true :someSymbol.to_proc # Would yield a proc object #
Now if we go through the array.map code from the Ruby library, we see that it executes a block of code on each element of the array.
array.map {|item| block } -> an_array
p [1,2,3,4,5].map(Proc.new{ |x| x + 1 }) # 2,3,4,5,6
If we create a simple block and pass it to the map method it would execute the code in the block for each element.
So the &: is actually &symbol and not &:something. Since the conversion of the to_proc method is not explicit the code
p [1,2,3,4,5].map(&:to_i)
is actually
p [1,2,3,4,5].map(&(Proc.new{|x| x.to_i}))
The to_proc method as found in Rails 2.3.5
def to_proc Proc.new { |*args| args.shift.__send__(self, *args) } end
Hope this helps someone