require 'thread' class Async # prevent dynamic ancestor method additions self.ancestors.each do |mod| next if self == mod class << mod alias :old_method_added :method_added def method_added(id) old_method_added(id) return unless self == Kernel or self == Object Async.hide(id) end end end def Async.hide(id) undef_method(id) end # make us a proxy @@keep = %w-__id__ __send__- (instance_methods - @@keep).each{|m| undef_method m} def initialize(&blk) @th = Thread.new(&blk) @th.abort_on_exception = true at_exit {@th.join} end def method_missing(sym, *args, &blk) __getobj__.__send__(sym, *args, &blk) end def __getobj__ @obj ||= @th.value end # control/status messages def arun @th.run self end def await @th.join end def aready? ! @th.alive? end def aresult_to(obj,meth) Async.new {obj.send(meth,__getobj__)} end end class Object def async(msg,*args,&blk) @async_queue ||= Queue.new fut = Async.new {Thread.stop;self.send(msg,*args,&blk)} @async_queue << fut @async_thread ||= Thread.new do loop{@async_queue.pop.arun.await; Thread.pass} end fut end end __END__