diff options
author | Benoit Daloze <[email protected]> | 2022-03-03 14:43:14 +0100 |
---|---|---|
committer | Benoit Daloze <[email protected]> | 2022-03-03 14:43:14 +0100 |
commit | 3b21818db1fac0c22f16364eab2d8cc0067abd63 (patch) | |
tree | 6776a6bfe92db4e35da1ff01e09c40d4c4c20351 /spec/ruby/core/array | |
parent | 1dc6bed0ca6ca379f1c4b2e9fc0dee72dbf1e205 (diff) |
Update to ruby/spec@82cd3a3
Diffstat (limited to 'spec/ruby/core/array')
-rw-r--r-- | spec/ruby/core/array/each_spec.rb | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/spec/ruby/core/array/each_spec.rb b/spec/ruby/core/array/each_spec.rb index 256647d61e..cf8e9da6d8 100644 --- a/spec/ruby/core/array/each_spec.rb +++ b/spec/ruby/core/array/each_spec.rb @@ -3,9 +3,10 @@ require_relative 'fixtures/classes' require_relative 'shared/enumeratorize' require_relative '../enumerable/shared/enumeratorized' -# Modifying a collection while the contents are being iterated -# gives undefined behavior. See -# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/23633 +# Mutating the array while it is being iterated is discouraged as it can result in confusing behavior. +# Yet a Ruby implementation must not crash in such a case, and following the simple CRuby behavior makes sense. +# CRuby simply reads the array storage and checks the size for every iteration; +# like `i = 0; while i < size; yield self[i]; end` describe "Array#each" do it "yields each element to the block" do @@ -15,6 +16,34 @@ describe "Array#each" do a.should == [1, 2, 3] end + it "yields each element to the block even if the array is changed during iteration" do + a = [1, 2, 3, 4, 5] + iterated = [] + a.each { |x| iterated << x; a << x+5 if x.even? } + iterated.should == [1, 2, 3, 4, 5, 7, 9] + end + + it "yields only elements that are still in the array" do + a = [0, 1, 2, 3, 4] + iterated = [] + a.each { |x| iterated << x; a.pop if x.even? } + iterated.should == [0, 1, 2] + end + + it "yields elements based on an internal index" do + a = [0, 1, 2, 3, 4] + iterated = [] + a.each { |x| iterated << x; a.shift if x.even? } + iterated.should == [0, 2, 4] + end + + it "yields the same element multiple times if inserting while iterating" do + a = [1, 2] + iterated = [] + a.each { |x| iterated << x; a.unshift(0) if a.size == 2 } + iterated.should == [1, 1, 2] + end + it "yields each element to a block that takes multiple arguments" do a = [[1, 2], :a, [3, 4]] b = [] |