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
ha开发者_JAVA技巧s 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.
精彩评论