Ruby 2: "Ленивое" вычисление размера (lazy size)
Примеры "ленивого" вычисления размера (lazy size) в Ruby 2, вычисление размера итератора "по требованию".
Enumerator#size может быть вызван для определения размера итератора (количества элементов, возвращаемых итератором) без вычисления всех элементов итератора (если возможно).
(1..100).to_a.permutation(4).size # => 94109400 loop.size # => Float::INFINITY (1..100).drop_while.size # => nil
При создании итераторов с помощью to_enum, Enumerator::New или Enumerator::Lazy::New также возможно определение size:
fib = Enumerator.new(Float::INFINITY) do |y|
  a = b = 1
  loop do
    y << a
    a, b = b, b+a
  end
end
still_lazy = fib.lazy.take(1_000_000).drop(42)
still_lazy.size # => 1_000_000 - 42
class Enumerable
  def skip(every)
    unless block_given?
      return to_enum(:skip, every) { size && (size+every)/(every + 1) }
    end
    each_slice(every+1) do |first, *ignore|
      yield last
    end
  end
end
(1..10).skip(3).to_a # => [1, 5, 9]
(1..10).skip(3).size # => 3, without executing the loop
Дополнительные детали и примеры можно посмотреть тут: to_enum