foo(&nil)与foo(&"不是proc")的行为有何不同?

And*_*imm 7 ruby null functional-programming

我发现了heckle

[1, 2, 3].each(&nil)
Run Code Online (Sandbox Code Playgroud)

不会导致任何错误 - 它只返回一个枚举器.

相比之下,

[1, 2, 3].each(&"")
Run Code Online (Sandbox Code Playgroud)

加薪

TypeError: wrong argument type String (expected Proc)
Run Code Online (Sandbox Code Playgroud)

还有,&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
Run Code Online (Sandbox Code Playgroud)

这不是因为NilClass实现to_proc- 我检查了RDoc.

我能理解为什么它会很好&nil,但我不确定它是如何完成的.这只是nil其他对象没有共享特殊行为的方式之一吗?

Pet*_* O. 8

通过查看Ruby的源代码可以找到答案.

Ruby 1.8:

查看block_pass文件中的函数eval.c.请注意,它nil专门处理Proc对象(宏NIL_P).如果函数传递了一个nil值,它会计算一个空块(我认为)并返回.在它检查对象是否是Proc对象(函数rb_obj_is_proc)之后的代码,如果不是,则引发异常"错误的参数类型(预期的Proc)".

Ruby 1.9.2:

查看caller_setup_args文件中的方法vm_insnhelper.c.to_proc只有在不是零的情况下才转换proc ; 否则,绕过类型转换和类型检查.