I think I understand it (roughly) now, and it doesn't need anything clever
like Fibers. Here's an implementation which runs under ruby-1.8.6:
module Enumerable
class Gen
include Enumerable
def initialize(&body)
@body = body
end
def each(&receiver)
@body.call(receiver)
end
end
def filter(&blk)
Gen.new do |y|
each do |*input|
blk.call(y, *input)
end
end
end
end
(1..10).
filter { |y,e| puts "Sending #{e.inspect}"; y[e]; puts "Sent" }.
filter { |y,e| y[e] if e % 2 == 0; sleep 0.5 }.
filter { |y,e| y[e + 100]; sleep 0.5 }.
each { |e| puts e }
Obviously I have just re-invented some very old wheel, whose name I don't
know, so apologies for the noise.
If 'map' and 'select' were implemented in this way, they wouldn't generate
intermediate arrays (Feature#708). Is there a library which does this
already?
Regards,
Brian.