红宝石中无限循环的块

时间:2014-09-23 09:58:42

标签: ruby infinite-loop

为什么下面这段代码导致3的无限循环?

a = [1,2,3,4,5,6,7,8,9,10]     
a.each {|value| puts a.insert(value,3)}

1 个答案:

答案 0 :(得分:3)

问题是insert更改了原始数组:

a = [1,2,3,4,5,6,7,8,9,10]
a.each do |value|
  a.insert(value, 3)
  p a
end

# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]                   # original, ^ marks current value
#  ^
# [1, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10]                # inserted 3 at position 1
#     ^
# [1, 3, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10]             # inserted 3 at position 3
#        ^
# [1, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10]          # inserted 3 at position 2
#           ^
# [1, 3, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10]       # inserted 3 at position 2
#              ^
# [1, 3, 3, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10]    # inserted 3 at position 2
#                 ^
# [1, 3, 3, 3, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10] # inserted 3 at position 2
#                    ^
# ...                                               # continues forever ...

你可能想要的是这样的东西:

a = [1,2,3,4,5,6,7,8,9,10]
a.each_index {|index| p a.dup.insert(index, 3) }
# [3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# [1, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# [1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10]
# [1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10]
# [1, 2, 3, 4, 3, 5, 6, 7, 8, 9, 10]
# [1, 2, 3, 4, 5, 3, 6, 7, 8, 9, 10]
# [1, 2, 3, 4, 5, 6, 3, 7, 8, 9, 10]
# [1, 2, 3, 4, 5, 6, 7, 3, 8, 9, 10]
# [1, 2, 3, 4, 5, 6, 7, 8, 3, 9, 10]
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 3, 10]
  • each_index遍历索引,而不是值。这可能是正确的做法,因为insert将索引作为第一个参数。
  • dup在每次迭代时复制数组,因此a保持不变。