http://rubymonk.com/learning/books/1/problems/148-array_of_fixnum
Ruby monk建议:
def array_of_fixnums?(array)
array.all? { |x| x.is_a? Fixnum }
end
这很好,但是以下代码在 irb 1.9.2 中有效,但在 rubymonk 传递空数组时失败:
def array_of_fixnums?(array)
result = false
array.each { |n|
if n.is_a? Fixnum
result = true
else
result = false
end }
result
end
以下是 IRB 输出:
1.9.2-p320 :001 > array_of_fixnums? []
=> false
以下是Rubymonk对我的解决方案的评价:
returns 'true' for [1,2,3] ✔
returns 'false' for ['a',1,:b] ✔
returns 'true' for []
RSpec::Expectations::ExpectationNotMetError
expected false to be true
我想知道为什么会这样?
根据答案更新:
def array_of_fixnums?(array)
result = true
array.each { |n| return false unless n.is_a? Fixnum }
result
end
您的代码有两个问题:
-
这个问题的措辞略显模糊。他们真正想要的是,如果任何元素不是 Fixnum,则返回 false,否则返回 true——所以空数组应该给出 true。如果你查看你的代码,你会发现
result
开始是假的,所以如果数组是空的,即使测试认为它应该是真的,它也会返回假。您可以通过从 true 开始来解决此问题。 -
您的代码实际上只是检测数组的最后一个元素是否为 Fixnum。让我们以数组
[1, "nope", 3]
为例。它将首先看到 1 并将result
设置为 true,然后它将看到"nope"并将result
设置为 false,然后它将看到 3 并将result
设置为 true,这就是该方法将返回的内容。RubyMonks 测试实际上不会检测到此错误,但它会显示在现实世界中。您希望在获得错误结果后立即返回,因为这足以确定数组并非全部是 Fixnum。
在这种情况下,您将永远不会进入每个循环,因为array
中没有元素。因此,您返回在上面行中设置为 false 的 result
的定义值。但是,如果数组中没有元素,则其所有元素都是 Fixnum,因此您应该返回 true。