https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112014-04-28T22:23:46ZRuby Issue Tracking SystemRuby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=463552014-04-28T22:23:46Ztenderlovemaking (Aaron Patterson)tenderlove@ruby-lang.org
<ul></ul><p>I also have this problem especially when debugging code where modules are mixed in at runtime, so I have to do something like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="o"><<</span> <span class="n">obj</span><span class="p">;</span> <span class="nb">self</span><span class="p">;</span> <span class="k">end</span><span class="p">.</span><span class="nf">ancestors</span><span class="p">.</span><span class="nf">find_all</span> <span class="p">{</span> <span class="o">|</span><span class="n">klass</span><span class="o">|</span>
<span class="n">klass</span><span class="p">.</span><span class="nf">method_defined?</span> <span class="ss">:foo</span>
<span class="p">}.</span><span class="nf">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">klass</span><span class="o">|</span> <span class="n">klass</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:foo</span><span class="p">).</span><span class="nf">source_location</span> <span class="p">}.</span><span class="nf">last</span>
</code></pre>
<p>(or something similar). A method to get the "super method" would be very convenient.</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=463582014-04-29T01:59:06Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/46358/diff?detail_id=33449">diff</a>)</li></ul><p>A patch.<br>
No tests yet.</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/proc.c b/proc.c
index 8153cc9..d1db478 100644
</span><span class="gd">--- a/proc.c
</span><span class="gi">+++ b/proc.c
</span><span class="p">@@ -1481,11 +1481,17 @@</span> method_owner(VALUE obj)
return defined_class;
}
<span class="gd">-void
-rb_method_name_error(VALUE klass, VALUE str)
</span><span class="gi">+struct method_name_error {
+ VALUE class_name;
+ const char *type;
+};
+
+static struct method_name_error
+prepare_method_name_error(VALUE klass)
</span> {
const char *s0 = " class";
VALUE c = klass;
<span class="gi">+ struct method_name_error e;
</span>
if (FL_TEST(c, FL_SINGLETON)) {
VALUE obj = rb_ivar_get(klass, attached);
<span class="p">@@ -1500,8 +1506,22 @@</span> rb_method_name_error(VALUE klass, VALUE str)
else if (RB_TYPE_P(c, T_MODULE)) {
s0 = " module";
}
<span class="gd">- rb_name_error_str(str, "undefined method `%"PRIsVALUE"' for%s `%"PRIsVALUE"'",
- QUOTE(str), s0, rb_class_name(c));
</span><span class="gi">+ e.class_name = rb_class_name(c);
+ e.type = s0;
+ return e;
+}
+
+#define method_name_error(klass, str, t) do { \
+ struct method_name_error e = prepare_method_name_error(klass); \
+ rb_name_error_str(str, t" method `%"PRIsVALUE"' for%s `%"PRIsVALUE"'", \
+ QUOTE(str), e.type, e.class_name); \
+ } while (0)
+
+
+void
+rb_method_name_error(VALUE klass, VALUE str)
+{
+ method_name_error(klass, str, "undefined");
</span> }
/*
<span class="p">@@ -2430,6 +2450,23 @@</span> method_proc(VALUE method)
return procval;
}
<span class="gi">+static VALUE
+method_super_method(VALUE method)
+{
+ struct METHOD *data;
+ VALUE defined_class, super_class;
+
+ TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
+ defined_class = data->defined_class;
+ if (BUILTIN_TYPE(defined_class) == T_MODULE) defined_class = data->rclass;
+ super_class = RCLASS_SUPER(defined_class);
+ if (!super_class) {
+ method_name_error(defined_class, rb_id2str(data->id), "no superclass");
+ }
+ return mnew(super_class, data->recv, data->id,
+ rb_obj_class(method), FALSE);
+}
+
</span> /*
* call-seq:
* local_jump_error.exit_value -> obj
<span class="p">@@ -2735,6 +2772,7 @@</span> Init_Proc(void)
rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
rb_define_method(rb_cMethod, "source_location", rb_method_location, 0);
rb_define_method(rb_cMethod, "parameters", rb_method_parameters, 0);
<span class="gi">+ rb_define_method(rb_cMethod, "super_method", method_super_method, 0);
</span> rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1);
rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1);
<span class="p">@@ -2756,6 +2794,7 @@</span> Init_Proc(void)
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0);
rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0);
<span class="gi">+ rb_define_method(rb_cUnboundMethod, "super_method", method_super_method, 0);
</span>
/* Module#*_method */
rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1);
</code></pre> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=463612014-04-29T04:24:42ZAnonymous
<ul></ul><p>I would also find this feature very useful when debugging large code bases with complicated class/module hierarchies.</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=463942014-04-30T07:13:51Zko1 (Koichi Sasada)
<ul></ul><p>What should happen on <code>#call</code> method with method objects returned from <code>super_method</code>?</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=464142014-04-30T16:35:44Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>It's an ordinary <code>Method</code> (or <code>UnboundMethod</code>) instance, same as <code>SuperClass.instance_method(:foo).bind(obj)</code>.</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=464162014-04-30T17:11:37Zko1 (Koichi Sasada)
<ul></ul><p>(2014/05/01 1:35), <a href="mailto:nobu@ruby-lang.org" class="email">nobu@ruby-lang.org</a> wrote:</p>
<blockquote>
<p>It's an ordinary <code>Method</code> (or <code>UnboundMethod</code>) instance, same as <code>SuperClass.instance_method(:foo).bind(obj)</code>.</p>
</blockquote>
<p>Oh, OK. I misunderstood the spec of Method class.</p>
<p>--<br>
// SASADA Koichi at atdot dot net</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=464352014-05-01T23:10:58Zzenspider (Ryan Davis)
<ul></ul><p>Maybe it is just me misunderstanding something... but this doesn't seem that complicated. I don't understand why you'd walk through the ancestors when you just just ask one level up:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">BigFoo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Foo</span> <span class="o"><</span> <span class="no">BigFoo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Object</span>
<span class="k">def</span> <span class="nf">super_method</span> <span class="nb">name</span>
<span class="nb">self</span><span class="p">.</span><span class="nf">class</span><span class="p">.</span><span class="nf">superclass</span><span class="p">.</span><span class="nf">instance_method</span> <span class="nb">name</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:bar</span><span class="p">).</span><span class="nf">source_location</span><span class="p">.</span><span class="nf">last</span> <span class="c1"># => 7</span>
<span class="nb">p</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">class</span><span class="p">.</span><span class="nf">superclass</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:bar</span><span class="p">).</span><span class="nf">source_location</span><span class="p">.</span><span class="nf">last</span> <span class="c1"># => 2</span>
<span class="nb">p</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">super_method</span><span class="p">(</span><span class="ss">:bar</span><span class="p">).</span><span class="nf">source_location</span><span class="p">.</span><span class="nf">last</span> <span class="c1"># => 2</span>
</code></pre> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=464392014-05-02T02:43:47Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>Hi,</p>
<p>Ryan Davis wrote:</p>
<blockquote>
<p>Maybe it is just me misunderstanding something... but this doesn't seem that complicated. I don't understand why you'd walk through the ancestors when you just just ask one level up:</p>
</blockquote>
<p>For one level, with simple class inheritance, it probably isn't, but throw in a prepended module or two, and the desire to go up more than one level (i.e. <code>obj.method(:foo).super_method.super_method</code>) and it's not completely trivial.</p>
<p>If ever we support a module being included more than once in the ancestry chain, then it's actually impossible (unless Method provides a more extensive api to tell where it is in the ancestry chain).</p>
<p>I'm +1 for this feature, although I would favor the shorter name <code>super</code>. I don't think it would ever conflict with the keyword, and if it did there is still the same solution as with <code>class</code>, i.e. <code>self.super</code>.</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=464402014-05-02T03:03:06Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>Nobuyoshi Nakada wrote:</p>
<blockquote>
<p>It's an ordinary <code>Method</code> (or <code>UnboundMethod</code>) instance, same as <code>SuperClass.instance_method(:foo).bind(obj)</code>.</p>
</blockquote>
<p>Agreed for <code>Method</code>, but I'm not sure I understand how we could define <code>UnboundMethod#super_method</code>, since a Module can be part of different ancestry chains.</p>
<pre><code># same example as original post continued
module M
def bar
end
end
Foo.include bar
Foo.ancestors # => [Foo, M, BigFoo, ...]
Foo.new.method(:bar).super_method.super_method.owner # => BigFoo
Foo.instance_method(:bar).super_method.super_method.owner # => Can't possible give meaningful result
</code></pre>
<p>(I didn't try the patch)</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=464412014-05-02T03:14:55Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>I must be tired.</p>
<p>Nobu: Sorry, I was confused, there's no problem with <code>UnboundMethod#super_method</code> because we retain which class this method was accessed from.</p>
<p>Ryan: That's actually a good example, there is no api to get the "original owner" of an unbound method, so in general it's not possible to implement <code>super_method</code> in Ruby. E.g. from <code>Hash.instance_method(:map)</code>, I don't know of a way to get back <code>Hash</code> in pure Ruby, and thus no way to go through Hash's ancestry chain.</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=464502014-05-02T08:47:41Zzenspider (Ryan Davis)
<ul></ul><p>Maybe I'm still not getting something. If you can call it (or super to it) you can grab it:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">BigFoo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Middle1</span> <span class="o"><</span> <span class="no">BigFoo</span><span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">Middle2</span> <span class="o"><</span> <span class="no">Middle1</span><span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">Middle3</span> <span class="o"><</span> <span class="no">Middle2</span><span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">Middle4</span> <span class="o"><</span> <span class="no">Middle3</span><span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">Middle5</span> <span class="o"><</span> <span class="no">Middle4</span><span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">Foo</span> <span class="o"><</span> <span class="no">Middle5</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Object</span>
<span class="k">def</span> <span class="nf">super_method</span> <span class="nb">name</span>
<span class="nb">self</span><span class="p">.</span><span class="nf">class</span><span class="p">.</span><span class="nf">superclass</span><span class="p">.</span><span class="nf">instance_method</span> <span class="nb">name</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:bar</span><span class="p">).</span><span class="nf">source_location</span><span class="p">.</span><span class="nf">last</span> <span class="c1"># => 13</span>
<span class="nb">p</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">class</span><span class="p">.</span><span class="nf">superclass</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:bar</span><span class="p">).</span><span class="nf">source_location</span><span class="p">.</span><span class="nf">last</span> <span class="c1"># => 2</span>
<span class="nb">p</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">super_method</span><span class="p">(</span><span class="ss">:bar</span><span class="p">).</span><span class="nf">source_location</span><span class="p">.</span><span class="nf">last</span> <span class="c1"># => 2</span>
</code></pre> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=464592014-05-02T15:02:12Zschneems (Richard Schneeman)
<ul></ul><p>Ryan, using <code>superclass</code> gets you really close, but doesn't handle extending object instances:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">BigFoo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Foo</span> <span class="o"><</span> <span class="no">BigFoo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Object</span>
<span class="k">def</span> <span class="nf">super_method</span> <span class="nb">name</span>
<span class="nb">self</span><span class="p">.</span><span class="nf">class</span><span class="p">.</span><span class="nf">superclass</span><span class="p">.</span><span class="nf">instance_method</span> <span class="nb">name</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">MixinFoo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="nb">puts</span> <span class="s2">"MixinFoo"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">foo</span> <span class="o">=</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span>
<span class="n">foo</span><span class="p">.</span><span class="nf">extend</span><span class="p">(</span><span class="no">MixinFoo</span><span class="p">)</span>
<span class="n">foo</span><span class="p">.</span><span class="nf">bar</span> <span class="c1"># => "MixinFoo"</span>
<span class="nb">puts</span> <span class="n">foo</span><span class="p">.</span><span class="nf">super_method</span><span class="p">(</span><span class="ss">:bar</span><span class="p">)</span>
<span class="c1">#<UnboundMethod: BigFoo#bar> # wrong return</span>
</code></pre>
<p>This is why my original code snippet uses <code>ancestors</code> rather than just <code>superclass</code>. We should see <code>MixinFoo</code> rather than <code>BigFoo</code>.</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=466232014-05-08T19:51:02Zjosh.cheek (Josh Cheek)josh.cheek@gmail.com
<ul></ul><p>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 <code>super_method</code> would completely miss.</p>
<p>Anyway, I'd like this method to exist also.</p>
<p>Here's how pry does it: <a href="https://github.com/pry/pry/blob/06341dfcdd53dc77e36761a974e6c930940dfb86/lib/pry/method.rb#L382" class="external">https://github.com/pry/pry/blob/06341dfcdd53dc77e36761a974e6c930940dfb86/lib/pry/method.rb#L382</a></p>
<p>Here's my crack at implementing it:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Method</span>
<span class="k">def</span> <span class="nf">super_method</span>
<span class="n">receiver</span><span class="p">.</span><span class="nf">singleton_class</span>
<span class="p">.</span><span class="nf">ancestors</span>
<span class="p">.</span><span class="nf">drop_while</span> <span class="p">{</span> <span class="o">|</span><span class="n">ancestor</span><span class="o">|</span> <span class="n">ancestor</span> <span class="o">!=</span> <span class="n">owner</span> <span class="p">}</span>
<span class="p">.</span><span class="nf">drop</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="p">.</span><span class="nf">first</span>
<span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span>
<span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span>
<span class="k">rescue</span> <span class="no">NameError</span>
<span class="k">raise</span> <span class="no">NameError</span><span class="p">,</span> <span class="s2">"No super method `</span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">' for `</span><span class="si">#{</span><span class="nb">inspect</span><span class="si">}</span><span class="s2">'"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">BigFoo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># toss in some superclass spam to show it doesn't matter</span>
<span class="k">class</span> <span class="nc">Foo</span> <span class="o"><</span> <span class="no">Class</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Class</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Class</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">BigFoo</span><span class="p">)))</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">MixinFoo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Foo</span><span class="p">.</span><span class="nf">new</span> <span class="c1"># => #<Foo:0x007fc123148728></span>
<span class="p">.</span><span class="nf">extend</span><span class="p">(</span><span class="no">MixinFoo</span><span class="p">)</span> <span class="c1"># => #<Foo:0x007fc123148728></span>
<span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:bar</span><span class="p">)</span> <span class="c1"># => #<Method: Foo(MixinFoo)#bar></span>
<span class="p">.</span><span class="nf">super_method</span> <span class="c1"># => #<Method: Foo(Foo)#bar></span>
<span class="p">.</span><span class="nf">super_method</span> <span class="c1"># => #<Method: Foo(BigFoo)#bar></span>
</code></pre> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=469742014-05-30T07:41:36Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-5 priority-4 priority-default closed" href="/issues/7836">Feature #7836</a>: Need a way to get Method and UnboundMethod objects to methods overridden by prepended modules</i> added</li></ul> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=471322014-06-10T08:32:57Zko1 (Koichi Sasada)
<ul><li><strong>Assignee</strong> set to <i>matz (Yukihiro Matsumoto)</i></li><li><strong>Target version</strong> set to <i>2.2.0</i></li></ul> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=471342014-06-10T08:51:07Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Feedback</i></li></ul><p>Having something like Method/UnboundMethod#super_method for debugging purpose is OK, but</p>
<ul>
<li>Is super_method is the right name? It sounds little bit weird for me.</li>
<li>I don't like Object#super_method.</li>
</ul>
<p>Matz.</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=471482014-06-10T18:07:32Zschneems (Richard Schneeman)
<ul></ul><p>I am also not in love with the naming. I would have preferred <code>Method#super</code> but we don't want to overwrite <code>super</code> or confuse functionality here. Maybe something along the lines of <code>get_super</code>. Does anyone have a better naming suggestion?</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=471692014-06-11T11:43:00Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>I also favor <code>super</code> (as I wrote before). It wouldn't overwrite the <code>super</code> keyword in most cases, and if it does (say from an instance method of Method) then there is still <code>self.super</code>.</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=480562014-07-26T08:23:43Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>OK, accepted.</p>
<p>The name should be 'super_method', since 'super' make me feel invocation of a mehtod in super class.<br>
The 'super_method' should return nil when there's no method in superclasses.</p>
<p>Matz.</p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=480572014-07-26T08:24:12Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul><li><strong>Status</strong> changed from <i>Feedback</i> to <i>Open</i></li><li><strong>Assignee</strong> changed from <i>matz (Yukihiro Matsumoto)</i> to <i>okkez (okkez _)</i></li></ul> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=480672014-07-26T16:22:51Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li></ul><p>Applied in changeset r46964.</p>
<hr>
<p>proc.c: method_super_method</p>
<ul>
<li>proc.c (method_super_method): new method Method#super_method,<br>
which returns a method object of the method to be called by<br>
<code>super</code> in the receiver method object.<br>
<a href="/issues/9781">[ruby-core:62202]</a> [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Feature Proposal: Method#super_method (Closed)" href="https://redmine.ruby-lang.org/issues/9781">#9781</a>]</li>
</ul> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=481642014-08-02T11:04:08Zaledovsky (Aleksandrs Ļedovskis)aleksandrs@ledovskis.lv
<ul></ul><p>Yukihiro Matsumoto wrote:</p>
<blockquote>
<p>OK, accepted.</p>
<p>The name should be 'super_method', since 'super' make me feel invocation of a mehtod in super class.<br>
The 'super_method' should return nil when there's no method in superclasses.</p>
<p>Matz.</p>
</blockquote>
<p>Wouldn't it be more consistent to name this method <code>supermethod</code>, i.e. without "_" in the middle?<br>
Thus it would be logical extension to <code>super<something></code> family, which now consists of <code>Class#superclass</code></p> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=487292014-09-08T13:51:02Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Has duplicate</strong> <i><a class="issue tracker-2 status-5 priority-4 priority-default closed" href="/issues/10216">Feature #10216</a>: Add methods to Method and UnboundMethod classess to retrieve method instance for super</i> added</li></ul> Ruby master - Feature #9781: Feature Proposal: Method#super_methodhttps://redmine.ruby-lang.org/issues/9781?journal_id=514632015-02-10T13:38:32ZEregon (Benoit Daloze)
<ul></ul><p>Marc-Andre Lafortune wrote:</p>
<blockquote>
<p>I must be tired.</p>
<p>Nobu: Sorry, I was confused, there's no problem with <code>UnboundMethod#super_method</code> because we retain which class this method was accessed from.</p>
<p>Ryan: That's actually a good example, there is no api to get the "original owner" of an unbound method, so in general it's not possible to implement <code>super_method</code> in Ruby. E.g. from <code>Hash.instance_method(:map)</code>, I don't know of a way to get back <code>Hash</code> in pure Ruby, and thus no way to go through Hash's ancestry chain.</p>
</blockquote>
<p>Actually there is a caveat with an UnboundMethod created with Module#instance_method, from a module (and not a class), as it has no idea what is the actual super method (as that can change in different ancestry chains).<br>
Instead it will just return a method if there is a module "M" included in the former module with a corresponding method, and that method might be somewhere in the ancestry of an object including M or not (if "M" was included after).</p>