我今天正在调试一些代码,当时我意识到Enumerable#all?的表现并不像我想象的那样。
我使用此方法确定何时立即返回值。它看起来像这样:
def some_method(hash)
unless hash.all? { |k, v| v.is_a? Float }
return hash
end
# some other business logic
end
但有时候这个方法会被发送一个空哈希,all?
的结果不是我所期望的。
以下是一些正常情景:
[7] pry(main)> {'count' => 1}.all? { |k, v| v.is_a? Float }
=> false
[8] pry(main)> {'count' => 2.5 }.all? { |k, v| v.is_a? Float }
=> true
这是奇怪的地方:
[6] pry(main)> {}.all? { |k, v| v.is_a? Float }
=> true
我不希望这会返回true,事实上我希望得到一个"No method .is_a? for NilClass"
,但我会回来。有谁知道这是为什么?
Ruby 2.2.0
答案 0 :(得分:1)
由于块永远不会被执行,因此无法抛出$sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com')";
错误(除了No method .is_a? for NilClass
已在Object
上实现,.is_a?
显然来自{ {1}}。)
有人可能希望NilClass
在空枚举器上返回Object
,但这就像是设计问题。
您可以单击文档中的all?
并确保方法“假设结果为true,并在第一个块返回false时将其设置为false”。此方法实现。
答案 1 :(得分:1)
文档的关键部分是"如果块永远不会返回false或nil,则该方法返回true。"
使用{}.all? { |k, v| v.is_a? Float }
块永远不会被执行(因为地图是空的)。因此,块永远不会返回false或nil,因此该方法返回true。
答案 2 :(得分:1)
当您查看documentation for the all?
method, as defined in the Enumeration Module in Ruby 2.2
如果块永远不返回false或nil
,则该方法返回true
all?
方法为可枚举的每个元素执行块。因为空哈希不包含任何迭代,所以块永远不会被执行。因此,该方法返回true