Ruby 2.7 adds warning for Proc.new and proc without block and error for lambda without block


In Ruby, following are the two ways in which we can pass a block to a method:

  • As an argument
  • As an anonymous block

Passing an argument is always considered better then anonymous block for various reasons:

  • It increases readability of the method.
  • If we pass block as an argument, then we get &block as Proc object. And in comparision to object, we can not do much with anonymous block.

Let’s define a method that calls a Proc.

# proc in a method
def sample_method
  proc
end
# => :sample_method

If we call this method without a block, then we’ll get ArgumentError.

# Method called without a block
sample_method
ArgumentError: tried to create Proc object without a block

We’ll also get ArgumentError if we use lambda instead of proc.

To handle this error, we need to explicitly add block_given? condition. Because method doesn’t tell us to pass anonymous block.

# proc in a method
def sample_method
  proc if block_given?
end
# => :sample_method

sample_method
#=> nil

That is why, Ruby 2.7 has added warning for Proc.new and proc without block in a method called with a block and errors for lambda without block in a method called with a block.

Before

We do not get any warning when Proc.new and proc is used without block in a method in earlier versions.

# proc without block in a method
def sample_method
  proc
end
# => :sample_method
# Method called with a block
sample_method { "Hello" }.call
# => "Hello"

We get a warning when lambda is used without block in a method.

# lambda without block in a method
def sample_method
  lambda
end
# => :sample_method
# Method called with a block
sample_method { "Hello" }.call
(irb):11: warning: tried to create Proc object without a block
# => "Hello"

Ruby 2.7

With Ruby 2.7, We will get a warning for Proc.new and proc without block in a method called with a block.

# proc without block in a method
def sample_method
  proc
end
# => :sample_method
# Method called with a block
sample_method { "Hello" }.call
(irb):65: warning: Capturing the given block using Proc.new is deprecated; use `&block` instead
# => "Hello"

It will give error for lambda without block in a method called with a block.

# lambda without block in a method
def sample_method
  lambda
end
# => :sample_method
# Method called with a block
sample_method { "Hello" }.call
ArgumentError (tried to create Proc object without a block)
# proc with block in a method
def sample_method(&block)
  proc &block
end
# => :sample_method
# Method called with a block
sample_method { "Hello" }.call
# => "Hello"
# lambda with block in a method
def sample_method(&block)
  lambda &block
end
# => :sample_method
# Method called with a block
sample_method { "Hello" }.call
# => "Hello"