From: "Marcin Rzeźnicki" Date: 2013-03-19T01:50:06+09:00 Subject: Finding one's way with 'super' in define_method/alias_emthod Hi all! This is my first post here, so please don't yell at me too harshly :-) I have a little problem with 'super' keyword when it is used in define_method/alias_method. First, a little example: class C def greetings p "Hello, #{caller.first}" end def curses p "Damn you, #{caller.first}" end end class D < C def greetings super end define_method :curses, instance_method(:greetings) end [3] pry(main)> D.new.greetings "Hello, (pry):11:in `greetings'" => "Hello, (pry):11:in `greetings'" [4] pry(main)> D.new.curses "Hello, (pry):11:in `greetings'" => "Hello, (pry):11:in `greetings'" So, as you can see 'super' is bound, perhaps a little unexpectedly, to a method instance rather than to its call site. You can see it clearly when inspecting the caller - in both cases it is 'greetings'. While this may seem logical and sound, it is quite troubling when you try to make a wrapper method around user-defined method doing metaprogramming tricks. For example, I am trying to implement the chain pattern like this: def chain new_method_name = "__#{@__chain_method}" chained_method = @__chain_method #.... alias_method new_method_name, chained_method private new_method_name remove_method chained_method define_method(chained_method) do |*args| send(new_method_name, *args) do |*yielded_args| #... end end unless method_defined? chained_method #... end In short, when a new method of given name is defined I alias it to some other name (__old_name) and then I define another method replacing user-defined method. In pseudo-code def execute #... end ends up as def __execute; end; def execute; ... send(__execute) ...; end; Works like a charm, except when original method contains super - it is supposed to call superclass' __execute, but it calls superclass execute instead and all this ends up with stack overflow (intended callchain should be: execute -> __execute(child) --> __execute(parent), but is: execute -> __execute(child) -> execute -> __execute(child)). Do you know any workaround? How can I overcome this problem and let super be bound correctly if used from aliased method? Thanks in advance for your opinions. -- Greetings Marcin Rzeźnicki