Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
require 'fiber' class Actor < Fiber class << self def spawn(&routine) actor = new &routine actor.instance_eval { @mailbox = Mailbox.new } Scheduler << actor actor end def receive(&filter) raise "receive must be called in the context of an Actor" unless current.is_a?(Actor) current.instance_eval { @mailbox.receive &filter } end end def <<(message) @mailbox << message Scheduler << self message end class Scheduler @@queue = [] @@running = false class << self def <<(actor) @@queue << actor run unless @@running end def run return if @@running @@running = true while not @@queue.empty? run_queue = @@queue @@queue = [] run_queue.each { |actor| actor.resume } end @@running = false end end end class Mailbox def initialize @queue = [] end def <<(message) @queue << message end def receive raise ArgumentError, "No filter block given" unless block_given? filter = Filter.new yield filter raise ArgumentError, "Empty filter" if filter.empty? matched_index = matched_message = action = nil while action.nil? @queue.each_with_index do |message, index| next unless (action = filter.match message) matched_index = index matched_message = message break end Fiber.yield unless action end @queue.delete_at matched_index return action.call(matched_message) end class Filter def initialize @ruleset = [] end def when(pattern, &action) raise ArgumentError, "No block given" unless action @ruleset << [pattern, action] end def match(message) _, action = @ruleset.find do |pattern, _| case pattern when Proc then pattern.call message else pattern === message end end action end def empty? @ruleset.empty? end end end end
This paste will be private.
From the Design Piracy series on my blog: