Tom Werner <tom / helmetstohardhats.org> 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

class Firetruck
  oldmethsym = Symbol.gensym
  alias_method oldmethsym, :put_out_fire
  class_eval %Q[
    def put_out_fire(options = {})
      #{oldmethsym}(options.merge({:material => :foam}))
    end
  ]
end

---------------------------------


Now in irb:
irb(main):132:0> load "c:\\temp\\firetruck.rb"
=> true
irb(main):133:0> Firetruck.new.put_out_fire
Extinguishing with options {:nozzle=>:big, :material=>:foam}
=> nil

Now, what I'd really like for doing stuff like this is an easy ruby
equivalent of lisp's quasi-quote, with the ability to nest levels of
quotation easily.  As it is, %Q[] combined with an eval that takes a
string helps in many practical cases where you want something vaguely
like bits of lisp's macro facility, but it's cumbersome to write
things like macro-generating macros, for example.