On Thu, Jun 08, 2006 at 08:15:21AM +0900, Rob Sanheim wrote:
> On 6/7/06, ara.t.howard / noaa.gov <ara.t.howard / noaa.gov> wrote:
> >whenever you wrap methods like this __always__, __always__, __always__ do 
> >this
> >
> >   alias_method "old_method", "method"
> >
> >   def method *a, &b
> >     # ...
> >     old_method *a, &b
> >     # ...
> >   end
> >
> >you need to collect any args and block and pass them through.
> >
> >regards.
> >
> 
> Thanks for the tip.  Besides that, are there any other gotchas related
> to redefining methods?

This one is at least as conspicuous as the above one, but just in case...

Try to come up with a more imaginative name than old_method for the old
definition, or you'll get SystemStackErrors when somebody also overrides it
using the same name...

If the method doesn't take a block (or you're running 1.9), you can also use
the following idiom:

old_meth = instance_method(:method)
define_method(:method) do |*a|  # &b too on 1.9
  # ...
  old_meth.bind(self).call(*a)  # ditto
  # ...
end

which is safer name-clash-wise, but note that this is slower than the
alias_method mechanism.

> For instance, I'm redefining my_foo inside
> module x, but y and z call my_foo before module x ever needs to get
> loaded.  Does that mean that my_foo will be the old version for y and
> z, then the new version for any callers after module x gets loaded?

Yes (if the later calls would see the new definition at all under the standard
method resolution rules).

-- 
Mauricio Fernandez  -   http://eigenclass.org   -  singular Ruby