true的未定义方法“每个”:TrueClass(NoMethodError)

时间:2019-12-13 12:07:46

标签: ruby for-loop nomethoderror

我正在Ruby中编写一个for循环,该循环遍历数组的元素,直到没有更多要读取的元素或满足条件为止。这是我的实现:

# 'all' is an array

exists = false

for i in all && !exists
  exists = all[i].has_card
end

正如标题所述,我遇到了此运行时错误:

undefined method `each' for true:TrueClass (NoMethodError)

我对Ruby还是很陌生,但我想问题是for循环试图遍历all!exists }。我该如何以自己想要的方式为它写一个?

编辑:如果可以用作澄清,这就是我将在C ++中实现的方式:

true

1 个答案:

答案 0 :(得分:2)

首先,eww。从未使用过for;这是Ruby的“滋润”。 :)

for item in items ... end由Ruby执行,就像您写了items.each do |item| ... end一样。 (实际上这就是Rubyists最初将其编写的方式。)等一下。

您的行解析为:

for i in (all && (!exists))

existsfalse时,!existstrue。现在,&&运算符将检查第一个参数是否为真。如果不是,则返回它;否则返回它。如果是,它将返回第二个参数。由于all可能是真实的,因此all && true返回第二个参数-true。

现在请记住,实际上,您的行在后台调用了要迭代的集合上的each方法。您的“集合”是true-根本不是集合。您无法在true上进行迭代。

如果您不想使用break(这有点不合理,可以引用我),则可以使用Enumerable模块中的其他方法。例如:

all.take_while { |item| !item.has_card }.each do |item|
  # ...
end

这比break方法要慢一点,因为它将构造一个中间数组,该数组仅包含前N个没有卡片的项目,以后将对其进行迭代,但是担心它为时过早优化。

编辑:不幸的是,塞巴斯蒂安删除了他们的答案,该答案具有正确的成语(尽管肯定取决于具体情况,我可能会比上面的答案写得早),所以我在这里重复一遍:

all.each do |item|
  break if item.has_card
  # ...
end