Enumerable#lazyrelies on your enumerated method #each. If your counter does not have a method #each, you cannot use #lazy. Now Kernel#enum_forthey #to_enumprovide the flexibility to specify an enumeration method other than #each:
Kernel
But #enum_forfriends always build simple (non-lazy) listings, never Enumerator::Lazy.
I see that Enumeratorin Ruby 1.9.3 it offers the same form #new:
Enumerator
Unfortunately, this constructor is completely removed in Ruby 2.0. Also I do not think that it was generally available on Enumerator::Lazy. So it seems to me that if I have a class with a method, I want to return a lazy enumerator, if this class does not #each, then I have to define some helper class that defines #each.
For example, I have a class Calendar. It makes no sense for me to suggest listing every date from the beginning of all time. #eachwill be useless. Instead, I suggest a method that lists (lazily) from the start date:
class Calendar
...
def each_from(first)
if block_given?
loop do
yield first if include?(first)
first += step
end
else
EachFrom.new(self, first).lazy
end
end
end
And this class is EachFromas follows:
class EachFrom
include Enumerable
def initialize(cal, first)
@cal = cal
@first = first
end
def each
@cal.each_from(@first) do |yielder, *vals|
yield yielder, *vals
end
end
end
It works, but it feels hard. Maybe I should subclass Enumerator::Lazyand define a constructor that would be deprecated from Enumerator. What do you think?