0

enum#detect说:

将枚举中的每个条目传递给阻塞。返回第一个不为假的块。如果没有对象匹配,则调用 ifnone 并在指定时返回其结果,否则返回 nil。

现在我正在尝试以下内容:

nil.call
#NoMethodError: undefined method `call' for nil:NilClass
#       from (irb):13
#       from C:/Ruby200/bin/irb:12:in `<main>'


(1..10).detect(x = 2) { |i| i % 5 == 0 and i % 7 == 0 }
#NoMethodError: undefined method `call' for 2:Fixnum
#       from (irb):15:in `detect'
#       from (irb):15
        from C:/Ruby200/bin/irb:12:in `<main>'

现在我的问题是为什么下面没有发生同样的错误:

(1..10).detect(x = nil) { |i| i % 5 == 0 and i % 7 == 0 }
#=> nil
(1..10).detect(x = nil) { |i| p x; i % 5 == 0 and i % 7 == 0 }
#nil
#nil
#nil
#nil
#nil
#nil
#nil
#nil
#nil
#nil
#=> nil
4

2 回答 2

1

如果您查看该方法的源代码(单击文档页面上的“查看源代码”),您会发现它仅在参数不是detect时才尝试执行:call nil

if (!NIL_P(if_none)) {
  return rb_funcall(if_none, id_call, 0, 0);
}
于 2013-03-29T18:37:33.960 回答
0

如果没有对象匹配,则调用 ifnone 并在指定时返回其结果,否则返回 nil。

我认为您对这句话的解析与预期的不同。这里的意思是:

if no object matches
  if ifnone is set
    return ifnone.call
  else
    return nil
  end
end

If you pass in nil as the argument, that counts as ifnone not being set, so it is not called. It will only be called if you pass a value other than nil for it.

于 2013-03-29T18:38:01.240 回答