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

时间:2021-04-22 06:36:22

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

另外,&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

It's not because NilClass implements to_proc - I checked the RDoc.

这不是因为NilClass实现了to_proc - 我检查了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?

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

1 个解决方案

#1


8  

The answer can be found by looking at Ruby's source code.

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

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.

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

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.

查看文件vm_insnhelper.c中的方法caller_setup_args。只有当它不是nil时,它才会将proc转换为to_proc;否则,绕过类型转换和类型检查。

#1


8  

The answer can be found by looking at Ruby's source code.

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

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.

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

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.

查看文件vm_insnhelper.c中的方法caller_setup_args。只有当它不是nil时,它才会将proc转换为to_proc;否则,绕过类型转换和类型检查。