From: Logan Capaldo Date: 2006-07-15T02:02:42+09:00 Subject: Re: Preferred monkeypatching technique On Jul 14, 2006, at 8:25 AM, Daniel Martin wrote: > Tom Werner writes: > >> 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 > > It seems to me that you're asking for a ruby version of gensym. (See > any lisp reference that talks about lisp macro writing) So let's try > to make something like that: > > # In the framework core > > class Firetruck > def put_out_fire(options = {}) > puts "Extinguishing with options #{options.inspect}" > end > end > > # In plugin1 > > class Symbol > def Symbol.gensym > @@gensym_count ||= 0 > @@gensym_count += 1 > ("__gensym__%X" % @@gensym_count).intern > end > end > > class Firetruck > oldmethsym = Symbol.gensym > alias_method oldmethsym, :put_out_fire > class_eval %Q[ > def put_out_fire(options = {}) > #{oldmethsym}(options.merge({:nozzle => :big})) > end > ] > end > > > ## Now, in plugin 2 > > # Note that the same exact code is included for gensym, but > # that this isn't a problem > class Symbol > def Symbol.gensym > @@gensym_count ||= 0 > @@gensym_count += 1 > ("__gensym__%X" % @@gensym_count).intern > end > end > > Neat idea, gensym in Ruby. I would suggest making it thread-safe though: % cat gensym.rb require 'mutex' class Symbol GensymLock = Mutex.new def self.gensym GensymLock.synchronize { @@gensym_count ||= 0 @@gensym_count += 1 ("__gensym__%X" % @@gensym_count).intern } end end And just require it whenever you need it. require 'gensym' sym = Symbol.gensym alias_method sym, :blah