I found out from heckle that
[1, 2, 3].each(&nil)
doesn't cause any errors - it just returns an enumerator.
By contrast,
[1, 2, 3].each(&"")
raises
TypeError: wrong argument type String (expected Proc)
Also, &nil
causes block_given? to return false
def block_given_tester
if block_given?
puts "Block given"
else
puts "Block not given"
end
end
block_given_tester(&nil) # => Block not given
It's not because NilClass
implements to_proc
- I checked the RDoc.
I can understand why it'd be nice to have &nil
, but I'm not sure how it's done. Is this just one of the ways nil
has special behavior not shared by other objects?
The answer can be found by looking at Ruby's source code.
Ruby 1.8:
Look at the function block_pass
in the file eval.c
. Note that it treats nil
specially from Proc
objects (the macro NIL_P
). If the function is passed a nil value, it evaluates an empty block (I think) and returns. The code right after it checks whether the object is a Proc
object (the function rb_obj_is_proc
) and raises the exception "wrong argument type (expected Proc)" if it isn't.
Ruby 1.9.2:
Look at the method caller_setup_args
in the file vm_insnhelper.c
. It converts the proc with to_proc
only
if it is not nil; otherwise, the type conversion and type check are bypassed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With