Q: 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?

A: 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    


A: Another option, which does not need to keep count of the number of calls to next:
class CycledArray
  def initialize(arr)
    @cycle = arr.cycle.each_with_index
    @iteration_length = arr.length
  end

  def next
    @cycle.next.first
  end

  def iterations
    @cycle.peek.last/@iteration_length
  end
end

arr = CycledArray.new([1,2,3])
56.times { arr.next }
arr.next
# => 3
arr.iterations
# => 19


A: This should work:
ary = [1,2,3]

ary.cycle.with_index do |n,i|
  iteration_number = i / ary.size
  puts "n: #{n} iteration: #{iteration_number}"
  break if i == 10
end


A: So many ways to do this, eh? You could also subclass Array, create an enumerator arr.cycle and step through it using Enumerator#next:
class CycleArr < Array
  def initialize arr
    @sz = arr.size
    @enum = arr.cycle
  end

  def next
    @count = (@count ||= 0) + 1
    @enum.next
  end

  def cycle_count
    1 + (@count - 1) % @sz
  end  
end

c = CycleArr.new(['dog', 'cat', 'pig'])
7.times { p [c.next, c.cycle_count] }
  # ["dog", 1]
  # ["cat", 2]
  # ["pig", 3]
  # ["dog", 1]
  # ["cat", 2]
  # ["pig", 3]
  # ["dog", 1]


A: Some of the answers above contain hidden problems in the way iteration/cycle_count is returned; for example, the iteration/count_cycle may be wrong if the data is requested before the iteration is checked. A more useful method would return [object, iteration] (analogous to the way #each_with_index returns [object, index]) and would take a block. 
Drawing from @Ursus and @7stud based on the similar question I asked here, I like this solution:
module Enumerable
  def each_with_iteration
    Enumerator.new do |y|
      iteration = 1
      enum = self.cycle
      loop do
        enum.peek # raises StopIteration if self.empty?
        self.size.times do
          e = [enum.next, iteration]
          y << (block_given? ? yield(e) : e)
        end
        iteration += 1
      end
    end
  end
end

This makes it a close analog to Enumerable#each_with_index, for example:
>> enum = %w(dog duck sheep rabbit).each_with_iteration
=> #<Enumerator: ...>
>> 7.times { p enum.next }
["dog", 1]
["duck", 1]
["sheep", 1]
["rabbit", 1]
["dog", 2]
["duck", 2]
["sheep", 2]
=> 7
>> enum.first(7)
=> [["dog", 1],
 ["duck", 1],
 ["sheep", 1],
 ["rabbit", 1],
 ["dog", 2],
 ["duck", 2],
 ["sheep", 2]]

And with a block:
>> animals = %w(dog duck sheep rabbit)
=> ["dog", "duck", "sheep", "rabbit"]
>> enum = animals.each_with_iteration { |animal, iter| "This is #{animal} number #{iter}" }
=> #<Enumerator: ...>
>> enum.first(7)
=> ["This is dog number 1",
 "This is duck number 1",
 "This is sheep number 1",
 "This is rabbit number 1",
 "This is dog number 2",
 "This is duck number 2",
 "This is sheep number 2"]

This also works as expected on a Hash, Set, Range, or other Enumerable.
EDIT: 


*

*Added a guard to keep from entering an infinite loop if self.empty? 

*Incorporated yield to operate on a block.
