Search code examples
rubyenumerator

Count iteration on the Enumerable cycle


I would like to use an enumerator like [1,2,3].cycle and count how many times I've gone through the iterations. [1,2,3].cycle.count creates an infinite loop and doesn't bring the iteration count. I'm playing a card game, and it cycles through the players. It's easy in the game to say:

@round = 0
if @turn == 1
  @round += 1
end

and it works. But I would like to know how to change count or add iter only for enumerators with cycle into something like this:

module Enumerable
  def cycle  
    super
    def count
      puts "Hi"
    end  
  end  
end  

Since everything in Ruby is an Object, I should be able to create functions within functions as this case works:

def x
  def y
    puts 1
  end
end
x.y
# => 1

How can I overwrite the behaviour of count only within a cycle enumerator or at least create a working method iter within the cycle Enumerator?


Solution

  • You can put something like that together fairly easily. Something like

    class Iter < Array
      attr_reader :iteration
    
      def initialize(*args)
        super(*args)
        @pointer = 0
        @iteration = 1 # Current iteration
      end
    
      def next
        self[@pointer].tap {
          @pointer = (@pointer + 1) % size
          @iteration += 1 if @pointer == 0
        }
      end
    end
    
    iter = Iter.new [1,2,3]
    
    7.times { puts 'iteration %d: %d' % [iter.iteration, iter.next] }
    
    # iteration 1: 1
    # iteration 1: 2
    # iteration 1: 3
    # iteration 2: 1
    # iteration 2: 2
    # iteration 2: 3
    # iteration 3: 1