class Enumerator
  def lazy_map(&blk) 
    Enumerator.new do |y|
      each do |e|
        y << blk[e]
      end
    end
  end

  def lazy_select(&blk)
    Enumerator.new do |y|
      each do |e|
        y << e if blk[e]
      end
    end
  end
end

class Fib
  def initialize(a=1,b=1)
    @a, @b = a, b
  end
  def each
    a, b = @a, @b
    yield a
    while true
      yield b
      a, b = b, a+b
    end
  end
end

Fib.new.to_enum.                                      # generator
  lazy_select { |x| x % 2 == 0 }.                     # filter
  lazy_map { |x| "<#{x}>" }.                          # filter
  each_with_index { |x,c| puts x; break if c >= 20 }  # consumer
