Saturday 15 August 2015

ruby - Modifying collection that was used in #cycle enumerator -



ruby - Modifying collection that was used in #cycle enumerator -

docs says

#cycle saves elements in internal array changes enum after first pass have no effect.

but following:

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

i think, according docs, 2 should never appear. missunderstanding something, bug/feature or outdated docs?

upd: case modifying after first pass

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

got it. saw array included enumerable, read docs enumerable#cycle , found inconsistency. indeed array implements own #cycle method, , there nil ... changes enum after first pass have no effect.

so docs ok. array's #cycle implemented it's internal array array itself. enumerator (or enumerable implementation) create internal array , collect values yielded #next until enumerator ends. #cycle go on iterating on internal array, can not modified ruby:

a = [1]; e = a.to_enum; c = e.cycle # => #<enumerator: #<enumerator: [1]:each>:cycle> c.next # => 1 # here e haven't reached end yet, alter still applied e.one? # => true << 2 # => [1, 2] c.next # => 2 # after next operation e finished... c.next # => 1 e.one? # => false # ... , changes ... << 3 # => [1, 2, 3] c.next # => 2 # ... not give effect c.next # => 1

ruby

No comments:

Post a Comment