From: Daniel Schierbeck Date: 2006-07-15T07:25:10+09:00 Subject: Re: Preferred monkeypatching technique transfire@gmail.com wrote: > Daniel Schierbeck wrote: >> 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? >> Not a solution, but: >> >> >> >> cut MyCut < Firetruck >> def put_out_fire(options = {}) >> super(options.merge(:nozzle => :big)) >> end >> end >> >> (Trans, can I omit the `MyCut <' part?) > > Sure. Although, the name provides a handle if you need to dynamically > effect the cut later --just like any Ruby class. But you can of course > do it annonymously too: > > Cut.new(Firetruck) do > ... > end Neat-o. How about a method-level shorthand? class Firetruck redef put_out_fire(options = {}) # maybe something other than "super"? super(options.merge(:nozzle => :big)) end end That way you can also easily cut a class from within itself, even conditionally. Cheers, Daniel