summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-enum-ext/mrblib/enum.rb59
-rw-r--r--mrbgems/mruby-enum-ext/test/enum.rb7
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