Feature #6712

Introduce super! for calling old definition when reopening classes

Added by Rodrigo Rosenfeld Rosas about 3 years ago. Updated about 3 years ago.

[ruby-core:<unknown>]
Status:Rejected
Priority:Normal
Assignee:Yukihiro Matsumoto

Description

ActiveSupport adds support for alias_method_chain which is a hack for being able to call the original method being overriden when reopening a class:

Extracted from documentation:

http://apidock.com/rails/ActiveSupport/CoreExtensions/Module/alias_method_chain

"Encapsulates the common pattern of:

alias_method :foo_without_feature, :foo
alias_method :foo, :foo_with_feature"

I'd prefer to have an official non-hacking way of achieving the same with just Ruby. Something simpler like:

class A
def a
2
end
end

class A
def a
super! * 3
end
end

A.new.a == 6

This way we wouldn't need to polute A with a_with_feature and a_without_feature methods if we're not interested on them.

History

#1 Updated by Shyouhei Urabe about 3 years ago

(1) I don't like the name
(2) It's not obvious what'd happen. What if A includes other module, which also define a method? alias_method_chain is clear about it because alias_method_chain is evaluated at the time of class loading. Your synatx delays it to actuall calling of the method.

#2 Updated by Marc-Andre Lafortune about 3 years ago

Hi,

I'd prefer to have an official non-hacking way of achieving the same with just Ruby. Something simpler like:

class A
def a
2
end
end

class A
def a
super! * 3
end
end

A.new.a == 6

This way we wouldn't need to polute A with a_with_feature and a_without_feature methods if we're not interested on them.

The alias_method_chain pattern is now obsolete with Module#prepend:

module Triple
def a
super * 3
end
end

class A
prepend Triple
end

A.new.a # => 6

#3 Updated by Rodrigo Rosenfeld Rosas about 3 years ago

@shyouhei, I think the behavior should be the same as the "prepend" behavior described by @marcandre.

def a
super! * 3
end

would be a short syntax for

prepend Module.new {
def a
super * 3
end
}

I'm not really worried about what name to use, but I guess most other names would only be possible for 3.0.

Another options could be "old_def", "old_definition", "old_method_definition", "old_super" or anything else you might prefer, I don't really care about the name.

#4 Updated by Shyouhei Urabe about 3 years ago

@rosenfeld remember eval.

def a
eval("super!") * 3
end

should what happen?

#5 Updated by Rodrigo Rosenfeld Rosas about 3 years ago

good catch :) Have no idea :P Just raise an exception "super! can't be used with eval" :)

#6 Updated by Marc-Andre Lafortune about 3 years ago

  • Status changed from Open to Rejected

Rejecting because of unworkability and no longer any use cases.

Also available in: Atom PDF