Block + Proc + Lambda

in Ruby

The definitive guide to blocks, procs, and lambdas in Ruby. There are a minor differences between all of them. By making this I hope to learn all of those differences and teach them at the same times.

Table of Contents
Type Syntax Definition Implicit Call Explicit Call

Type

Not Object

Object - class Proc

Object - class Proc


Syntax

The syntax for defining an group of code to be executed later is the same for blocks, procs, and lambdas.
Single line syntax:

# basic example
{ puts 'I made it here' }

# example with params
{ |user| puts "say hi #{user.name}" }
      
Multi line syntax:

# basic example
do
  puts 'I made it here'
end

# example with params
do |user|
  puts "say hi #{user.name}"
end
      

Definition

A block can only be defined while calling a method.


some_method do
  puts 'these are the contents of a block'
end
      

A proc can be defined by newing up the Proc class or using the Kernal#proc method.


proc_1 = Proc.new { 'Hello World'}
proc_2 = proc { 'Hello World'}
      

A lambda can be defined by using the -> syntax or using the Kernal#lambda method.


lambda_1 = ->{ 'Hello World'}
lambda_2 = lambda { 'Hello World'}
      

Implicit Call

A block can be called implicitly with the "yield" keyword without an explicit argument in the method declaration.


def some_method
  yield
end

some_method do
  puts 'these are the contents of a block'
end
      

To use a proc implicitly, you can pass the last argument of the method in with a special "&" syntax to convert to proc to a block.


def some_method
  yield
end

p = proc { puts 'convert this proc to a block!'}

some_method(&p)
      

Since a lambda is a proc, it works the same as above!


def some_method
  yield
end

lamb = ->{ puts 'convert this lambda to a block!'}

some_method(&lamb)
      

Explicit Call

A block can be called explicitly by using "&block" syntax. The "&" calls "to_proc" on the "block" variable and converts it to a proc. That makes it an object and gives it the "call" method to call the proc.


def some_method(&block)
  block.call
end
      

Procs have a "call" method that you use to call the method.


some_proc = proc { puts 'some test' }
some_proc.call
      

Since lambdas are just types of procs, they have the same "call" method to call them.


some_lambda = ->{ puts 'some test' }
some_lambda.call