From: Benoit Cerrina Date: 2001-12-20T17:49:11+09:00 Subject: [ruby-talk:29085] Re: overriding methods: (almost) a replacement for alias_method what is instance_method, I can't find the doc for it in programming ruby? Benoit "Paul Brannan" wrote in message news:20011219135044.P6125@atdesk.com... > I think almost all of us will agree that it's pretty ugly to do: > > class Foo > alias_method :old_foo, :foo > def foo > # do stuff > old_foo() > end > end > > Well, I was playing around with define_method() last night, and I came > up with this idea: when I include a module, an anonymous base class is > created from the included module. So if I could create a temporary > module with one method, have that method be an alias for the method I > want to override, and include it in the current class, then I could call > the original function with a simple call to super(): > > class Foo > def foo > puts "foo!" > end > > tmp_module = Module.new > tmp_module.__send__(:define_method, :foo, instance_method(:foo)) > include tmp_module > > def foo > puts "foo 2!" > super() > end > end > > Foo.new.foo > > This produces: > > foo 2! > foo! > > The problem is that this doesn't work quite the way I would expect. If > I try to override the new foo(), such as with: > > class Foo > def foo > puts "foo!" > end > > tmp_module = Module.new > tmp_module.__send__(:define_method, :foo, instance_method(:foo)) > include tmp_module > > def foo > puts "foo 2!" > super() > end > > tmp_module = Module.new > tmp_module.__send__(:define_method, :foo, instance_method(:foo)) > include tmp_module > > def foo > puts "foo 3!" > super() > end > end > > Then I get: > > foo 3! > foo 2! > ... > foo2.rb:11:in `foo': stack level too deep (SystemStackError) > from foo2.rb:11:in `foo' > from foo2.rb:12:in `foo' > from foo2.rb:12:in `foo' > from foo2.rb:12:in `foo' > from foo2.rb:12:in `foo' > from foo2.rb:12:in `foo' > from foo2.rb:12:in `foo' > from foo2.rb:12:in `foo' > ... 6360 levels... > from foo2.rb:12:in `foo' > from foo2.rb:21:in `foo' > from foo2.rb:21:in `foo' > from foo2.rb:25 > > So it seems that "foo 3" makes a call to super(), which calls "foo 2". > Then "foo 2" makes a call to super(), which also calls "foo 2".... This > sort of makes sense, because "foo 2" was defined in class Foo, and class > Foo's base class is the anonymous class in which "foo 2" is defined. > > I feel really horrible being so close to a solution to this problem > (finding an alternative for alias_method), but not being quite there. > Does anyone have some ideas for how this idea could be extended or > enhanced to achieve the desired result? > > Paul >