Forum: Ruby-core Feature Proposal: Method#super_method

Db953d125f5cc49756edb6149f1b813e?d=identicon&s=25 richard s. (richard_s)
on 2014-05-02 17:02
(Received via mailing list)
Issue #9781 has been updated by Richard Schneeman.


Ryan, using superclass gets you really close, but doesn't handle
extending object instances:

```
class BigFoo
  def bar
  end
end

class Foo < BigFoo
  def bar
    super
  end
end

class Object
  def super_method name
    self.class.superclass.instance_method name
  end
end


module MixinFoo
  def bar
    puts "MixinFoo"
  end
end

foo = Foo.new
foo.extend(MixinFoo)
foo.bar # => "MixinFoo"

puts foo.super_method(:bar)
#<UnboundMethod: BigFoo#bar> # wrong return
```

This is why my original code snippet uses ancestors rather than just
superclass. We should see `MixinFoo` rather than `BigFoo`.

----------------------------------------
Feature #9781: Feature Proposal: Method#super_method
https://bugs.ruby-lang.org/issues/9781#change-46459

* 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#met...). 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.
This topic is locked and can not be replied to.