diff options
| -rw-r--r-- | mrbgems/mruby-enum-ext/mrblib/enum.rb | 59 | ||||
| -rw-r--r-- | mrbgems/mruby-enum-ext/test/enum.rb | 7 |
2 files changed, 63 insertions, 3 deletions
diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb index 0ce1d7605..50eaa6a4d 100644 --- a/mrbgems/mruby-enum-ext/mrblib/enum.rb +++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -518,9 +518,62 @@ module Enumerable # def reverse_each(&block) - ary = [] - self.each {|*val| ary.push(val.__svalue) } - ary.reverse_each(&block) + ary = self.to_a + i = ary.size - 1 + while i>=0 + block.call(ary[i]) + i -= 1 + end self end + + ## + # call-seq: + # enum.cycle(n=nil) { |obj| block } -> nil + # enum.cycle(n=nil) -> an_enumerator + # + # Calls <i>block</i> for each element of <i>enum</i> repeatedly _n_ + # times or forever if none or +nil+ is given. If a non-positive + # number is given or the collection is empty, does nothing. Returns + # +nil+ if the loop has finished without getting interrupted. + # + # Enumerable#cycle saves elements in an internal array so changes + # to <i>enum</i> after the first pass have no effect. + # + # If no block is given, an enumerator is returned instead. + # + # a = ["a", "b", "c"] + # a.cycle { |x| puts x } # print, a, b, c, a, b, c,.. forever. + # a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c. + # + + def cycle(n=nil, &block) + ary = [] + if n == nil + self.each do|*val| + ary.push val + block.call(*val) + end + loop do + ary.each do|e| + block.call(*e) + end + end + else + unless n.kind_of? Integer + raise TypeError, "expected Integer for 1st argument" + end + + self.each do|*val| + ary.push val + end + count = 0 + while count < n + ary.each do|e| + block.call(*e) + end + count += 1 + end + end + end end diff --git a/mrbgems/mruby-enum-ext/test/enum.rb b/mrbgems/mruby-enum-ext/test/enum.rb index 127b263fb..68f2781b7 100644 --- a/mrbgems/mruby-enum-ext/test/enum.rb +++ b/mrbgems/mruby-enum-ext/test/enum.rb @@ -122,3 +122,10 @@ assert("Enumerable#reverse_each") do assert_equal (1..3), r.reverse_each { |v| a << v } assert_equal [3, 2, 1], a end + +assert("Enumerable#cycle") do + a = [] + ["a", "b", "c"].cycle(2) { |v| a << v } + assert_equal ["a", "b", "c", "a", "b", "c"], a + assert_raise(TypeError) { ["a", "b", "c"].cycle("a") { |v| a << v } } +end |
