class Generator
Public Class Methods
new(enum = nil, &block)
click to toggle source
Creates a new generator either from an Enumerable
object or from a block.
In the former, block is ignored even if given.
In the latter, the given block is called with the generator itself, and expected to call the yield
method for each element.
# File lib/sequence/generator.rb, line 76 def initialize(enum = nil, &block) if enum @block = proc{|g| enum.each{|value| g.yield value}} else @block = block end @index = 0 @queue = [] @main_thread = nil @loop_thread.kill if defined?(@loop_thread) @loop_thread = Thread.new do Thread.stop begin @block.call(self) rescue @main_thread.raise $! ensure @main_thread.wakeup end end Thread.pass until @loop_thread.stop? self end
Public Instance Methods
current()
click to toggle source
Returns the element at the current position.
# File lib/sequence/generator.rb, line 160 def current raise EOFError.new("no more elements available") if end? @queue.first end
each() { |next| ... }
click to toggle source
Rewinds the generator and enumerates the elements.
# File lib/sequence/generator.rb, line 172 def each rewind until end? yield self.next end self end
end?()
click to toggle source
Returns true if the generator has reached the end.
# File lib/sequence/generator.rb, line 117 def end? if @queue.empty? if @main_thread raise "should not be called in Generator.new{|g| ... }" end Thread.critical = true begin @main_thread = Thread.current @loop_thread.wakeup Thread.stop rescue ThreadError # ignore ensure @main_thread = nil Thread.critical = false end end @queue.empty? end
index()
click to toggle source
Returns the current index (position) counting from zero.
# File lib/sequence/generator.rb, line 143 def index @index end
next()
click to toggle source
Returns the element at the current position and moves forward.
# File lib/sequence/generator.rb, line 153 def next raise EOFError.new("no more elements available") if end? @index += 1 @queue.shift end
next?()
click to toggle source
Returns true if the generator has not reached the end yet.
# File lib/sequence/generator.rb, line 138 def next? !end? end
pos()
click to toggle source
Returns the current index (position) counting from zero.
# File lib/sequence/generator.rb, line 148 def pos @index end
rewind()
click to toggle source
Rewinds the generator.
# File lib/sequence/generator.rb, line 166 def rewind initialize(nil, &@block) if @index.nonzero? self end
yield(value)
click to toggle source
Yields an element to the generator.
# File lib/sequence/generator.rb, line 101 def yield(value) if Thread.current != @loop_thread raise "should be called in Generator.new{|g| ... }" end Thread.critical = true begin @queue << value @main_thread.wakeup Thread.stop ensure Thread.critical = false end self end