修改#cycle枚举器中使用的集合

时间:2014-10-31 11:42:39

标签: ruby

Docs

  

#cycle将元素保存在内部数组中,因此在第一次传递后对枚举的更改无效。

但我得到以下内容:

a = [1]; x = a.cycle
x.next #=> 1
x.next #=> 1

a << 2
x.next #=> 2
x.next #=> 1

a = [1]; a.cycle { |x| puts x; a << x + 1; sleep 1 }
1
2
3

我认为,根据文档,2永远不会出现。我错过了解某些内容,这是一个错误/功能还是过时的文档?

UPD: 首次通过后修改的案例

a = [1]; passed = 0; a.cycle { |x| puts x; if passed > 2; a << x + 1; else; passed += 1; end; sleep 1 }
1
1
1
1
2
3

1 个答案:

答案 0 :(得分:0)

知道了。我看到Array包含Enumerable,阅读Enumerable#cycle的文档并发现不一致。但确实Array实现了自己的#cycle方法,并且... so changes to enum after the first pass have no effect没有任何内容。

所以文档还可以。实现了数组的#cycle,它的内部数组就是数组本身。但枚举器(或任何Enumerable实现)将创建内部数组并将#next产生的值收集到其中,直到枚举器结束。然后#cycle继续迭代这个内部数组,不能从ruby修改:

a = [1]; e = a.to_enum; c = e.cycle
# => #<Enumerator: #<Enumerator: [1]:each>:cycle> 
c.next
# => 1

# Here e haven't reached its end yet, so any change is still applied
e.one?
# => true 
a << 2
# => [1, 2] 
c.next
# => 2 

# after next operation e will be finished...
c.next
# => 1
e.one?
# => false  

# ... and now any changes ...
a << 3
# => [1, 2, 3] 
c.next
# => 2 

# ... will not give any effect
c.next
# => 1