summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorksss <[email protected]>2016-11-11 15:49:17 +0900
committerksss <[email protected]>2016-11-11 16:53:42 +0900
commit126d55480d9668a6a313a8e8c428cccfb88d459e (patch)
tree66e9950c6f07f3a15a6a65255fc0ce3a8569fe98
parent3d946a80443e2af77bcd3e5e1860b3229d2f02c5 (diff)
downloadmruby-126d55480d9668a6a313a8e8c428cccfb88d459e.tar.gz
mruby-126d55480d9668a6a313a8e8c428cccfb88d459e.zip
Reimplement Enumerable#cycle
Fix pattern of infinite loop And support all specs in https://github.com/ruby/spec/blob/27960d06e0ce92c37f074450f0eab4b0519b118c/core/enumerable/cycle_spec.rb without Enumerable#size
-rw-r--r--mrbgems/mruby-enum-ext/mrblib/enum.rb49
1 files changed, 26 insertions, 23 deletions
diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb
index a5f661ce6..6724dff37 100644
--- a/mrbgems/mruby-enum-ext/mrblib/enum.rb
+++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb
@@ -573,35 +573,38 @@ module Enumerable
# a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c.
#
- def cycle(n=nil, &block)
- return to_enum(:cycle, n) if !block && n.nil?
+ def cycle(nv = nil, &block)
+ return to_enum(:cycle, nv) unless block
- ary = []
- if n.nil?
- self.each do|*val|
- ary.push val
- block.call(*val)
+ n = nil
+
+ if nv.nil?
+ n = -1
+ else
+ unless nv.respond_to?(:to_int)
+ raise TypeError, "no implicit conversion of #{nv.class} into Integer"
end
- loop do
- ary.each do|e|
- block.call(*e)
- end
+ n = nv.to_int
+ unless n.kind_of?(Integer)
+ raise TypeError, "no implicit conversion of #{nv.class} into Integer"
end
- else
- raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
+ return nil if n <= 0
+ end
- n = n.to_int
- self.each do|*val|
- ary.push val
- end
- count = 0
- while count < n
- ary.each do|e|
- block.call(*e)
- end
- count += 1
+ ary = []
+ each do |*i|
+ ary.push(i)
+ yield(*i)
+ end
+ return nil if ary.empty?
+
+ while n < 0 || 0 < (n -= 1)
+ ary.each do |i|
+ yield(*i)
end
end
+
+ nil
end
##