Ruby foo(&;nil)的行为与foo(";not a proc";)有何不同?

Ruby foo(&;nil)的行为与foo(";not a proc";)有何不同?,ruby,functional-programming,null,Ruby,Functional Programming,Null,我从赫克尔那里发现的 [1, 2, 3].each(&nil) 不会导致任何错误-它只返回一个枚举数 相比之下 [1, 2, 3].each(&"") 提高 TypeError: wrong argument type String (expected Proc) 另外,&nil会导致给定的阻塞吗?归假 def block_given_tester if block_given? puts "Block given" else puts "Block

我从赫克尔那里发现的

[1, 2, 3].each(&nil)
不会导致任何错误-它只返回一个枚举数

相比之下

[1, 2, 3].each(&"")
提高

TypeError: wrong argument type String (expected Proc)
另外,
&nil
会导致给定的阻塞吗?归假

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
具有其他对象不共享的特殊行为的方式之一吗?

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

Ruby 1.8:

查看文件
eval.c
中的函数
block\u pass
。请注意,它专门从
Proc
对象(宏
nil\u P
)处理
nil
。如果函数被传递一个nil值,它将计算一个空块(我想)并返回。代码检查对象是否为
Proc
对象(函数
rb_obj_是\u Proc
),如果不是,则引发异常“错误的参数类型(预期的过程)”

Ruby 1.9.2:

查看文件
vm\u insnhelper.c
中的方法
caller\u setup\u args
。它仅将带有
的过程转换为\u proc

如果不是零;否则,类型转换和类型检查将被忽略。

我假设您看到的是1.8分支中的一个,而不是1.9分支中的一个。是的,这是来自Ruby 1.8的,因为这是我可用的代码。我现在下载Ruby 1.9.2的代码,看看是否有任何变化。