Understanding the &: Ruby syntax

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

The official definition

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

Advertisements