`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
```
MODIFY
mrbgems/mruby-enum-chain/mrblib/chain.rb
mrbgems/mruby-enum-chain/mrblib/chain.rb
@@ -17,13 +17,19 @@ class Enumerator
include Enumerable
def initialize(*args)
- @enums = args
+ @enums = args.freeze
+ @pos = -1
end
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
end
@@ -36,11 +42,10 @@ class Enumerator
end
def rewind
- i = @enums.size - 1
- while 0 <= i
- e = @enums[i]
+ while 0 <= @pos && @pos < @enums.size
+ e = @enums[@pos]
e.rewind if e.respond_to?(:rewind)
- i -= 1
+ @pos -= 1
end
self

MODIFY
mrbgems/mruby-enum-chain/test/enum_chain.rb
mrbgems/mruby-enum-chain/test/enum_chain.rb
@@ -76,13 +76,24 @@ assert("Enumerator::Chain#size") do
end
assert("Enumerator::Chain#rewind") do
- rewound = []
+ rewound = nil
e1 = [1, 2]
e2 = (4..6)
- (class << e1; self end).define_method(:rewind) { rewound << __id__ }
- (class << e2; self end).define_method(:rewind) { rewound << __id__ }
- c = e1.chain(e2).each{}.rewind
- assert_equal [e2.__id__, e1.__id__], rewound
+ (class << e1; self end).define_method(:rewind) { rewound << self }
+ (class << e2; self end).define_method(:rewind) { rewound << self }
+ c = e1.chain(e2)
+
+ 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
assert("Enumerator::Chain#+") do

`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
  ```