From: Daniel Berger Date: 2006-07-14T08:50:09+09:00 Subject: Re: Preferred monkeypatching technique Tom Werner wrote: > Allow me to present a scenario: > > class Firetruck > def put_out_fire(options = {}) > # code > end > end > > Pretend Firetruck is in a 3rd party application (like Rails) that is > happy to allow plugins to modify core code. Now, let's say I want to > write some code that always adds a certain attribute to the options > hash. I could do this: > > class Firetruck > alias_method :__old_put_out_fire, :put_out_fire > def put_out_fire(options = {}) > __old_put_out_fire(options.merge({:nozzle => :big})) > end > end > > Which works just fine until someone else comes up with a plugin that > wants to modify the same method (doing something similar to me) and > just so happens to also use :__old_put_out_fire as THEIR alias. Now > we've got my plugin's method as the alias calling itself, which leads > to, you know, badness. > > So I'm wondering if there's a better way. Perhaps some way to turn > Firetruck into an ancestor of itself, so to speak, so that my plugin > would create a new Firetruck class, pushing the old Firetruck backward > in the chain and allowing me to call super instead and preventing > alias_method explosions. Or would that just end up causing more havoc? > > Tom > Perhaps add a namespace? # monkey.rb class Foo def monkey "hello" end def test "test" end end module Test class Foo < ::Foo def monkey "world" end end end foo1 = Foo.new foo2 = Test::Foo.new foo1.monkey # "hello" foo2.monkey # "world" foo1.test # "test" foo2.test # "test" Hm, this thread actually gives me more fodder for my previous idea of having objects store aliases for later reference. We could then emit a warning if you define an alias that already exists. :) HTH, Dan