On Apr 6, 2006, at 12:16 PM, Austin Ziegler wrote:

> On 4/6/06, Yukihiro Matsumoto <matz / ruby-lang.org> wrote:
>> It still sounds like bad manner for the same reason.  Besides it's  
>> not
>> thread safe.  If I were designing Transaction::Simple, I'd create
>> t_foo as a delegation object to the original foo.  But I might be
>> still missing something.
>
> That might work and I can investigate that. Ultimately, the trick with
> that mode of operation is that changes to the t_foo object *must* be
> reflected to the foo object, but only if the block exits without error
> or an explicit #commit_transaction call is made.
>
> The other thing that would make me happy is the ability to not have
> Marshal#dump break if I have a Proc. ;)
>
> -austin
> --
> Austin Ziegler * halostatue / gmail.com
>                * Alternate: austin / halostatue.ca

Incidentally the last time someone asked this question I wrote this  
code:

% cat quasiextender.rb
require 'delegate'
module QuasiExtender
   def quasi_extend(mod)
     @__quasi_extensions ||= []
     @__quasi_extensions << mod
   end

   def quasi_retract(mod)
     @__quasi_extensions ||= []
     @__quasi_extensions.delete_if { |ext| ext == mod }
   end


   def method_missing(name, *args, &block)
     @__quasi_extensions ||= []
     meth = nil
     found_mod = nil
     @__quasi_extensions.each do |ext|
        begin
          meth = ext.instance_method(name.to_sym)
          found_mod = ext
        rescue NameError, NoMethodError
          next
        else
          break
        end
     end

     if meth.nil? # we didn't find it
        super
     else
        sneaky_class = Class.new(SimpleDelegator) {
                 include(found_mod)
        }
        sneaky_obj = sneaky_class.new(self)

        meth.bind(sneaky_obj).call(*args, &block)
     end
   end
end

It of course has various disadvantages, and you can't use it on  
itself :-p