Search code examples
rubyargumentsblock

Expected ArgumentError but got NoMethodError


When I call individual methods in the classes below, I was expecting ArgumentError, but I see:

class A
  def with_one_argument(&block)
    block.call
  end
end

A.new.with_one_argument
# => NoMethodError: undefined method `call' for nil:NilClass

But this acts as expected:

class B
  def with_one_argument(some_value)
    puts some_value
  end
end

B.new.with_one_argument
# => ArgumentError: wrong number of arguments (0 for 1)

Can anybody explain why (&block) is treated as special? In my understanding, if I do not provide a default value to an argument then ArgumentError is expected.


Solution

  • Nothing complicated. The fact is simply that a block is not an argument. With A, if you pass a block, that would be referred to as block as a converted proc, otherwise block has the value nil. But in either case, block is the result of converting the passed block (which is neither an argument nor an object) to a proc (which is an object).