summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorKOBAYASHI Shuji <[email protected]>2019-08-30 15:46:29 +0900
committerKOBAYASHI Shuji <[email protected]>2019-09-02 08:58:33 +0900
commit66211394e1597e403f14aada81a993f5b1429066 (patch)
tree105373cb13dccf72c8fcd90a496a21c1da9b5b5f
parent0ce1878abafcaa84e373de144480aaadfff3039b (diff)
downloadmruby-66211394e1597e403f14aada81a993f5b1429066.tar.gz
mruby-66211394e1597e403f14aada81a993f5b1429066.zip
`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 ```
-rw-r--r--mrbgems/mruby-enum-chain/mrblib/chain.rb19
-rw-r--r--mrbgems/mruby-enum-chain/test/enum_chain.rb21
2 files changed, 28 insertions, 12 deletions
diff --git a/mrbgems/mruby-enum-chain/mrblib/chain.rb b/mrbgems/mruby-enum-chain/mrblib/chain.rb
index 55474eb92..43d0926c8 100644
--- a/mrbgems/mruby-enum-chain/mrblib/chain.rb
+++ b/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
diff --git a/mrbgems/mruby-enum-chain/test/enum_chain.rb b/mrbgems/mruby-enum-chain/test/enum_chain.rb
index 1d3d691ca..45bbc9a77 100644
--- a/mrbgems/mruby-enum-chain/test/enum_chain.rb
+++ b/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