Commit 66211394 authored by KOBAYASHI Shuji's avatar KOBAYASHI Shuji

`Enumerator::Chain#rewind` shouldn't rewind elements aren't iterated

### Example:

  ```ruby
  # example.rb
  e = [1]
  def e.rewind; p :r end
  c = e.chain(e)
  c.each{break c}.rewind
  ```

#### Before this patch:

  ```terminal
  $ bin/mruby example.rb
  :r
  :r
  ```

#### After this patch (same as Ruby):

  ```terminal
  $ bin/mruby example.rb
  :r
  ```
parent 0ce1878a
...@@ -17,13 +17,19 @@ class Enumerator ...@@ -17,13 +17,19 @@ class Enumerator
include Enumerable include Enumerable
def initialize(*args) def initialize(*args)
@enums = args @enums = args.freeze
@pos = -1
end end
def each(&block) def each(&block)
return to_enum unless block_given? return to_enum unless block
@enums.each { |e| e.each(&block) } i = 0
while i < @enums.size
@pos = i
@enums[i].each(&block)
i += 1
end
self self
end end
...@@ -36,11 +42,10 @@ class Enumerator ...@@ -36,11 +42,10 @@ class Enumerator
end end
def rewind def rewind
i = @enums.size - 1 while 0 <= @pos && @pos < @enums.size
while 0 <= i e = @enums[@pos]
e = @enums[i]
e.rewind if e.respond_to?(:rewind) e.rewind if e.respond_to?(:rewind)
i -= 1 @pos -= 1
end end
self self
......
...@@ -76,13 +76,24 @@ assert("Enumerator::Chain#size") do ...@@ -76,13 +76,24 @@ assert("Enumerator::Chain#size") do
end end
assert("Enumerator::Chain#rewind") do assert("Enumerator::Chain#rewind") do
rewound = [] rewound = nil
e1 = [1, 2] e1 = [1, 2]
e2 = (4..6) e2 = (4..6)
(class << e1; self end).define_method(:rewind) { rewound << __id__ } (class << e1; self end).define_method(:rewind) { rewound << self }
(class << e2; self end).define_method(:rewind) { rewound << __id__ } (class << e2; self end).define_method(:rewind) { rewound << self }
c = e1.chain(e2).each{}.rewind c = e1.chain(e2)
assert_equal [e2.__id__, e1.__id__], rewound
rewound = []
c.rewind
assert_equal [], rewound
rewound = []
c.each{break c}.rewind
assert_equal [e1], rewound
rewound = []
c.each{}.rewind
assert_equal [e2, e1], rewound
end end
assert("Enumerator::Chain#+") do assert("Enumerator::Chain#+") do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment