Coroutine

Coroutines are program components like subroutines. Coroutines are more generic and flexible than subroutines, but are less widely used in practice. Coroutines were first introduced natively in Simula. Coroutines are well suited for implementing more familiar program components such as cooperative tasks, iterators, infinite lists, and pipes.

Usage

  count = (ARGV.shift || 1000).to_i
  input = (1..count).map { (rand * 10000).round.to_f / 100}

  Producer = Coroutine.new do |me|
    loop do
      1.upto(6) do
        me[:last_input] = input.shift
        me.resume(Printer)
      end
      input.shift # discard every seventh input number
    end
  end
  Printer = Coroutine.new do |me|
    loop do
      1.upto(8) do
        me.resume(Producer)
        if Producer[:last_input]
          print Producer[:last_input], "\t"
          Producer[:last_input] = nil
        end
        me.resume(Controller)
      end
      puts
    end
  end

  Controller = Coroutine.new do |me|
    until input.empty? do
      me.resume(Printer)
    end
  end

  Controller.run
Methods
Attributes
[R] stopped
Public Class methods
new(data = {}) {|self| ...}
# File lib/facets/more/coroutine.rb, line 69
  def initialize(data = {})
    @data = data
    callcc do |@continue|
      return
    end
    yield self
    stop
  end
Public Instance methods
[](name)
# File lib/facets/more/coroutine.rb, line 101
  def [](name)
    @data[name]
  end
[]=(name, value)
# File lib/facets/more/coroutine.rb, line 105
  def []=(name, value)
    @data[name] = value
  end
resume(other)
# File lib/facets/more/coroutine.rb, line 90
  def resume(other)
    callcc do |@continue|
      other.continue(self)
    end
  end
run()
# File lib/facets/more/coroutine.rb, line 80
  def run
    callcc do |@stopped|
      continue
    end
  end
stop()
# File lib/facets/more/coroutine.rb, line 86
  def stop
    @stopped.call
  end
Protected Instance methods
continue(from = nil)
# File lib/facets/more/coroutine.rb, line 96
  def continue(from = nil)
    @stopped = from.stopped if not @stopped and from
    @continue.call
  end