Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Patch Enumemator to play well with EM::Sunchrony
class Enumerator
class Error < Struct.new(:error)
end
def feed(v)
@feed = v
end
class StopIteration < ::StopIteration
attr :result
def initialize(msg, result)
super(msg)
@result = result
end
end
def next_values
raise @stop if @stop
if @peek
peek, @peek = @peek, nil
return peek
end
@fiber ||= Fiber.new do |parent|
begin
result = each {|*args|
parent, feed = parent.transfer args
feed
}
parent.transfer StopIteration.new("iteration reached an end", result)
rescue Exception => e
parent.transfer Error.new(e)
end
end
feed, @feed = @feed, nil
result = @fiber.transfer Fiber.current, feed
case result
when StopIteration
@fiber.resume
@fiber = nil
@stop = result
raise result
when Error
@fiber = nil
raise result.error
end
result
end
def _ary2sv(v, dup)
case v
when Array
case v.size
when 0 then nil
when 1 then v[0]
else
dup ? v.dup : v
end
else
v
end
end
def next
_ary2sv(next_values, false)
end
def peek
@peek ||= next_values
_ary2sv(@peek, true)
end
end
require './enumerator_patch'
EM.synchrony do
start = Time.now
enum = Enumerator.new do |y|
3.times do |i|
EM::Synchrony.sleep 1
y.yield i+100
end
end
enum = enum.each_with_index
puts "! #{enum.next.inspect}"
puts "Time: #{Time.now - start}"
EM.stop
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.