This page contains automated test results for code from O'Reilly's Ruby Cookbook. If this code looks interesting or useful, you might want to buy the whole book.

Synchronizing Access to an Object
CodeExpectedActual
require 'thread'
class Object
  def synchronize
    mutex.synchronize { yield self }
  end
  def mutex
    @mutex ||= Mutex.new
  end
end
list = []
Thread.new { list.synchronize { |l| sleep(5); 3.times { l.push "Thread 1" } } }
Thread.new { list.synchronize { |l| 3.times { l.push "Thread 2" } } }
sleep(6)
list
["Thread 1", "Thread 1", "Thread 1", "Thread 2", "Thread 2", "Thread 2"] ["Thread 1", "Thread 1", "Thread 1", "Thread 2", "Thread 2", "Thread 2"]
list = []
Thread.new { list.synchronize { |l| sleep(5); 3.times { l.push "Thread 1" } } }
Thread.new { 3.times { list.push "Thread 2" } }
sleep(6)
list
["Thread 2", "Thread 2", "Thread 2", "Thread 1", "Thread 1", "Thread 1"] ["Thread 2", "Thread 2", "Thread 2", "Thread 1", "Thread 1", "Thread 1"]
require 'aspectr'
require 'thread'
class Synchronized < AspectR::Aspect
  def lock(method_sym, object, return_value, *args)
    object.mutex.lock
  end
  def unlock(method_sym, object, return_value, *args)
    object.mutex.unlock
  end
end
array = %w{do re mi fa so la ti}
Synchronized.new.wrap(array, :lock, :unlock, :push, :pop, :each)
Thread.new { array.each { |x| puts x } }
Thread.new do
  puts 'Destroying the array.'
  array.pop until array.empty?
  puts 'Destroyed!'
end
do
re
mi
fa
so
la
ti
Destroying the array.
Destroyed!
class_eval '
	  def push(*args,&block)
	    return (__aop__-605355376_1687822(*args,&block)) unless Aspect.dispatch?
	    begin
	     exit_status = nil
	     self.class.__aop_call_advice(:PRE, 'push', self, exit_status,*args,&block)
	     exit_status = []
	     return (exit_status.push(__aop__-605355376_1687822(*args,&block)).last)
	    rescue Exception
	     exit_status = true
	     raise
	    ensure
	     self.class.__aop_call_advice(:POST, 'push', self, exit_status,*args,&block)
	    end
	  end
	'
class_eval '
	  def pop(&block)
	    return (__aop__-605355376_1689870(&block)) unless Aspect.dispatch?
	    begin
	     exit_status = nil
	     self.class.__aop_call_advice(:PRE, 'pop', self, exit_status,&block)
	     exit_status = []
	     return (exit_status.push(__aop__-605355376_1689870(&block)).last)
	    rescue Exception
	     exit_status = true
	     raise
	    ensure
	     self.class.__aop_call_advice(:POST, 'pop', self, exit_status,&block)
	    end
	  end
	'
class_eval '
	  def each(&block)
	    return (__aop__-605355376_983310(&block)) unless Aspect.dispatch?
	    begin
	     exit_status = nil
	     self.class.__aop_call_advice(:PRE, 'each', self, exit_status,&block)
	     exit_status = []
	     return (exit_status.push(__aop__-605355376_983310(&block)).last)
	    rescue Exception
	     exit_status = true
	     raise
	    ensure
	     self.class.__aop_call_advice(:POST, 'each', self, exit_status,&block)
	    end
	  end
	'
do
re
mi
fa
so
la
ti
Destroying the array.
Destroyed!