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