Skip to content

Block, Procs and Lambdas

Blocks are methods without names. They are usually used together with iterators. The blocks starts with a do and finish with an end. Alternatively blocks use curl braces {}.

[1,2,3,4].each do |n|
    puts n
end

using curly braces for blocks :

[1,2,3,4].each { |n|
    puts n
}

Yield keyword

Pass control between a method and block and back as required. The yield executes the block associated with the method.

If we run the we call a method without a block an error will be thrown :

def no_block
 yield
end
:no_block

and calling the method without a block yield an error :

no_block
LocalJumpError: no block given (yield)
    from (irb):2:in `no_block'

Define another method and call the method with a block :

def block_demo
yield
end

And calling the method with a block yields the right result :

block_demo { puts "Hello World" }
=> Hello World

Lets run some code in the block and in the method as follows :

 def hello
   puts "In the Method"
   yield
   puts "Back in the method"
   yield
 end

and using it as follows :

hello { puts "You are in the block" }

We can also access parameters from the block as follows :

def hello
  puts "Hello Person"
  yield "Joe"
  puts "Hello Person"
  yield "Peter"
end

and calling as follows :

hello {|name| puts "Hello #{name}"}

We can also check if the block is provided or not as follows :

def hello
  puts "Hello Person"
  yield "Joe", "Bloggs" if block_given?
  puts "Hello Person"
  yield "Peter", "Pan" if block_given?
end

and calling the method as follows :

hello {|first_name, last_name| puts "Hello #{first_name} #{last_name}"}

Passing blocks into methods

Blocks can be used as parameters into a method. The parameter should be preceded with & character as follows :

def my_iterator(x, &b)
  i = 0
  while(i < x)
    b.call(i*x) # Use call with block parameter
    i += 1
  end
end

We can invoke the block code by using the method call on the block variable. We can use use the block as follows :

my_iterator(5){|x| p x}

Note that the parameter needs to be the last argument in the method.

Procs

A block that can be stored to a variable and executed

times_two = Proc.new do |n|
  n * 2
end

and using it :

puts [1,2, 3].collect(&times_two)
# The & convert the Proc to a block

We can also call the Proc directly using the call method as follows :

times_two.call 4

Lambdas

Same as Procs but uses alternative syntax

def lambda_test(my_lambda)
  puts "Method here"
  my_lambda.call
end

and using it :

lambda_test(lambda {puts "Lambda here"})