diff options
| author | ksss <[email protected]> | 2016-11-11 15:49:17 +0900 |
|---|---|---|
| committer | ksss <[email protected]> | 2016-11-11 16:53:42 +0900 |
| commit | 126d55480d9668a6a313a8e8c428cccfb88d459e (patch) | |
| tree | 66e9950c6f07f3a15a6a65255fc0ce3a8569fe98 /mrbgems/mruby-enum-ext | |
| parent | 3d946a80443e2af77bcd3e5e1860b3229d2f02c5 (diff) | |
| download | mruby-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
Diffstat (limited to 'mrbgems/mruby-enum-ext')
| -rw-r--r-- | mrbgems/mruby-enum-ext/mrblib/enum.rb | 49 |
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 ## |
