Strange Array#每个Ruby行为

时间:2012-07-01 20:25:56

标签: ruby

问题有点模糊,但我不确定为什么会这样:

我有以下代码:

p user.room.users.length
user.room.users.each {|usr| puts "b" }
user.room.users.each {|usr| puts "a"; usr.enter(Room[Config::entrance]) }

输出:

5
b
b
b
b
b
a
a
a

我还让用户#输入计数被调用的次数,它返回3!我对这种行为感到困惑。我怀疑User#enter中的代码是原因,但如果有人认为它可能是相关的,我可以提供它(我不想不必要地混淆这个问题)。


修改

如果相关我正在使用ruby-1.9.3-p125

2 个答案:

答案 0 :(得分:7)

当您在迭代时更改集合时,通常会发生这种行为。因此,usr.enter会修改user.room.user,以解释您所看到的行为。

答案 1 :(得分:2)

正如@ sepp2k所说,大概usr.enter正在修改user.room.users。虽然我从未查看过源代码,Array#each似乎可以通过维护当前元素的内部索引,并在每次迭代后递增该索引来实现(实际上,这是它可能的唯一合理方式 work)。

所以说你从[1,2,3]开始,在#each的第一次迭代中,删除第一个元素。对于第二次迭代,它将产生数组的第二个元素,但现在数组为[2,3],因此第二个元素为3。所以你会错过一个元素。