From: josh.cheek@... Date: 2014-05-08T19:51:03+00:00 Subject: [ruby-core:62467] [ruby-trunk - Feature #9781] Feature Proposal: Method#super_method Issue #9781 has been updated by Josh Cheek. I've only ever needed to do this in codebases like Rails, where there's an insane amount of inheritance. However, Rails also relies heavily on method_missing, which `super_method` would completely miss. Anyway, I'd like this method to exist also. Here's my crack at implementing it: ``` class Method def super_method receiver.singleton_class .ancestors .drop_while { |ancestor| ancestor != owner } .drop(1) .first .instance_method(name) .bind(receiver) rescue NameError raise NameError, "No super method `#{name}' for class `#{owner}'" end end class BigFoo def bar end end class Foo < Class.new(Class.new(Class.new(BigFoo))) def bar end end module MixinFoo def bar end end Foo.new # => # .extend(MixinFoo) # => # .method(:bar) # => # .super_method # => # .super_method # => # ``` ---------------------------------------- Feature #9781: Feature Proposal: Method#super_method https://bugs.ruby-lang.org/issues/9781#change-46623 * Author: Richard Schneeman * Status: Open * Priority: Normal * Assignee: * Category: core * Target version: ---------------------------------------- When `super` is called in a method the Ruby VM knows how to find the next ancestor that has that method and call it. It is difficult to do this manually, so I propose we expose this information in Method#super_location. Ruby Method class (http://www.ruby-doc.org/core-2.1.1/Method.html) is returned by calling Object.method and passing in a method name (http://www.ruby-doc.org/core-2.1.1/Object.html#method-i-method). This is useful for debugging: ```ruby # /tmp/code.rb class Foo def bar end end puts Foo.new.method(:bar).source_location # => ["/tmp/code.rb", 3] ``` The Object#method allows a ruby developer to easily track the source location of the method and makes debugging very easy. However if the code is being invoked by a call to `super` it is difficult to track down: ```ruby # /tmp/code.rb class BigFoo def bar end end class Foo < BigFoo def bar super end end ``` In this code sample it is easy to find the method definition inside of Foo but it is very difficult in large projects to find what code exactly `super` is calling. This simple example is easy, but it can be hard when there are many ancestors. Currently if I wanted to find this we can inspect ancestors ```ruby Foo.ancestors[1..-1].map do |ancestor| next unless ancestor.method_defined?(:bar) ancestor.instance_method(:bar) end.compact.first.source_location ``` To make this process simpler I am proposing a method on the Method class that would return the result of `super` It could be called like this: ```ruby Foo.new.method(:bar).super_method ``` I believe adding Method#super_method, or exposing this same information somewhere else, could greatly help developers to debug large systems easily. -- https://bugs.ruby-lang.org/