Blocks

Blocks in ruby are anonymous functions that can be passed into methods.

Calling Blocks

Blocks can be called using the yield keyword or by calling .call, the latter is called an explicit block while the former is called an implicit block.

  • explicit block: Using .call to execute a block
  def explicit_block(&block)
    block.call
  end
  explicit_block { puts "Explicit block called" }
  • implicit block: using yield to execute a block
  # block passed as anonymous function
  def test_method
    yield
  end
  test_method { puts "Block is being run" }

  # block with parameters
  def one_two_three
    yield 1
    yield 2
    yield 3
  end
  one_two_three { |number| puts number * 10 }
  # 10, 20, 30

Proc

a proc is an instance of the Proc class and is similar to a block. As opposed to a block, a proc is a Ruby object which can be stored in a variable and therefore reused many times throughout a program.

# A proc is defined by calling Proc.new followed by a block.
square = Proc.new { |x| x ** 2 }

# Calling a proc with .call method.
square.call(2)
# => 4

# When passing a proc to a method,
# an `&` is used to convert the proc into a block.
[2, 4, 6].collect!(&square)
# => [4, 16, 36]

Lambda

a lambda is an object similar to a proc. Unlike a proc, a lambda requires a specific number of arguments passed to it

say_something = -> { puts "This is a lambda" }
say_something.call
# => "This is a lambda"

parameterized_lambda = -> (x) { puts x** 2 }
parameterized_lambda.call(2)
# => 4

difference in Procs and Lambdas

  • lamdas returns to its calling method and executes the statement after the lamda was called while proc returns from the calling method and doesn’t execute the following code.
  def proc_demo_method
    proc_demo = Proc.new { return "Only I print!" }
    proc_demo.call
    "But what about me?" # Never reached
  end

  puts proc_demo_method
  # Output
  # Only I print!

  # (Notice that the proc breaks out of the method
  # when it returns the value.)

  def lambda_demo_method
    lambda_demo = lambda { return "Will I print?" }
    lambda_demo.call
    "Sorry - it's me that's printed."
  end

  puts lambda_demo_method
  # Output
  # Sorry - it's me that's printed.

  # (Notice that the lambda returns back to the method
  # in order to complete it.)
  • Procs do not check the number of arguments, whereas Lambdas do.
lam = lambda { |x| puts x } #produces a lambda with one argument
lam.call(2) # prints out 2
lam.call # ArgumentError: insufficient arguments (0 for 1)
lam.call(1,2,3) #ArgumentError: insufficient arguments (3 for 1)

proc = Proc.new { |x| puts x } # creates a proc with one argument
proc.call(2) # prints out 2
proc.call # returns nil
proc.call(1,2,3) # prints 1 and disregards the extra #arguments