Class: Coroutine

Inherits:
Object show all
Defined in:
lib/more/facets/coroutine.rb

Overview

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

Instance Method Summary collapse

Constructor Details

#initialize(data = {}) {|_self| ... } ⇒ Coroutine

Returns a new instance of Coroutine.

Yields:

  • (_self)

Yield Parameters:

  • _self (Coroutine)

    the object that the method was called on



77
78
79
80
81
82
83
84
# File 'lib/more/facets/coroutine.rb', line 77

def initialize(data = {})
  @data = data
  callcc do |@continue|
    return
  end
  yield self
  stop
end

Instance Method Details

#[](name) ⇒ Object



109
110
111
# File 'lib/more/facets/coroutine.rb', line 109

def [](name)
  @data[name]
end

#[]=(name, value) ⇒ Object



113
114
115
# File 'lib/more/facets/coroutine.rb', line 113

def []=(name, value)
  @data[name] = value
end

#resume(other) ⇒ Object



98
99
100
101
102
# File 'lib/more/facets/coroutine.rb', line 98

def resume(other)
  callcc do |@continue|
    other.continue(self)
  end
end

#runObject



88
89
90
91
92
# File 'lib/more/facets/coroutine.rb', line 88

def run
  callcc do |@stopped|
    continue
  end
end

#stopObject



94
95
96
# File 'lib/more/facets/coroutine.rb', line 94

def stop
  @stopped.call
end