Blocks,Lambda and Procs in Ruby

Block in a piece of code enclosed with {} or do…end.


test {puts "You are in a block"}

How to use block?

Case 1: Passing a block to a function not as a function argument : Use ‘yield’ to access

if a block is passed to a function , function can run it’s code using yield. If at the time of calling the function, block is not passed then accessing the block would throw exception. So the better way is to check before using that block is passed or not in the function and to check this you can use block_given? . Check the below examples for better understanding.

def speak
  puts yield

def speak_safe
	puts yield if block_given?

#calling this function by passing block {"hello"}
speak { "Hello" }

#calling this function by passing block do "hello" end
speak do "hello" end 

#calling this function by passing block {"hello"}
speak_safe { "Hello" }

#calling this function without passing block 
#LocalJumpError: no block given (yield)

#calling this function without passing block 

Case 2: Passing a block to a function as a function argument : Using ‘call’ to access

Prepend ‘&’ in the last argument name if block is passed in it. In case both * and & are present in the argument list, & should come later. Block attached to this method is converted to a Proc object and gets assigned to that last argument. You can use yield here too.

def speak(&block)

#calling this function by passing block {"hello"}
speak() {"hello"} #same as speak hello

#calling this function without passing block 
speak() #or speak
#NoMethodError: undefined method `call' for nil:NilClass

Blocks which expect values

Arguments can be passed to blocks.For this within the block, you list the names of the arguments to receive the parameters between vertical bars ( |..| ).

def multiply(&block)
	puts yield(10,20)
	puts block.class

#calling function by passing block
test() {|i,j| i*j}

#Proc (Read the complete article to get an idea about Proc) 

Explanation : Block { |i,j| i*j} is passed to function and using and yield , block runs.


Procs in Ruby are first-class objects, since they can be created during runtime, stored in data structures, passed as arguments to other functions and returned as the value of other functions.

p ={|i| i*2}

If you put & in front of a Proc instance in the argument position, that will be interpreted as a block.Using this logic block is passed to a function and later get called.

def check(&t) #t is a Proc object
	puts t.class

p ={puts "hello"}
check(&p) #passing block not proc



lambda is used to create Proc object. It’s same as Proc except some minor differences.

a = lambda {|k| puts k}
#<Proc:0x007faf706258f0@(irb):70 (lambda)> 
#It's creating a proc object.Please note.

def multiply(block)

l = lambda {|a,b| a*b}
#<Proc:0x007faf74933340@(irb):75 (lambda)> 

p = {|a,b| a*b}


Many times you have seen in code statements like:
#[1,2,3,4....800] (all order ids)

#Same as{|o|}
#[1,2,3,4....800] (all order ids)

But have you ever wondered how come this works? Given is the reason:

The & operator is combined with :method_name (&:method_name), which is not a Proc instance, so implicit class cast applies Symbol#to_proc to it, which gives ->x{x.method_name}

#reverse is a String function to reverse
my_proc = :reverse.to_proc 

For more information please visit this blog

comments powered by Disqus