foo(&nil) 的行为与 foo(&“not a proc”) 有何不同?
我从 heckle 中发现这
[1, 2, 3].each(&nil)
不会导致任何错误 - 它只是返回一个枚举器。
相比之下,
[1, 2, 3].each(&"")
raises
TypeError: wrong argument type String (expected Proc)
Also, &nil
会导致 block_given?返回 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
这不是因为 NilClass
实现了 to_proc
- 我检查了 RDoc。
我可以理解为什么拥有&nil
会很好,但我不确定如何它是完成的。这是否只是 nil
具有其他对象未共享的特殊行为的方式之一?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通过查看Ruby的源代码可以找到答案。
Ruby 1.8:
查看文件
eval.c
中的函数block_pass
。请注意,它特别对待来自Proc
对象(宏NIL_P
)的nil
。如果函数传递一个 nil 值,它会计算一个空块(我认为)并返回。紧接着的代码检查该对象是否为Proc
对象(函数rb_obj_is_proc
),如果不是,则引发异常“错误的参数类型(预期的 Proc)” 。Ruby 1.9.2:
查看文件
vm_insnhelper.c
中的方法caller_setup_args
。它仅使用to_proc
转换 proc如果不为零;否则,类型转换和类型检查将被绕过。
The answer can be found by looking at Ruby's source code.
Ruby 1.8:
Look at the function
block_pass
in the fileeval.c
. Note that it treatsnil
specially fromProc
objects (the macroNIL_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 aProc
object (the functionrb_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 filevm_insnhelper.c
. It converts the proc withto_proc
onlyif it is not nil; otherwise, the type conversion and type check are bypassed.