Bug #7842

An alias of a "prepend"ed method skips the original method when calling super

Added by Yusuke Endoh about 1 year ago. Updated 3 months ago.

[ruby-core:52206]
Status:Closed
Priority:Normal
Assignee:Nobuyoshi Nakada
Category:core
Target version:2.1.0
ruby -v:ruby 2.0.0dev (2013-02-13 trunk 39225) [x86_64-linux] Backport:1.9.3: DONTNEED, 2.0.0: DONE

Description

Hello,

module P
def m; puts "P"; super; end
end
class A
def m; puts "A"; end
end
class B < A
def m; puts "B"; end
prepend P
alias m2 m
end
B.new.m2
#=> expected: P, B, A
#=> actual: P, A

Is this intentional?
It looks weird to me that calling super of P#m (as m2) skips A#m.

Yusuke Endoh mame@tsg.ne.jp


Related issues

Related to ruby-trunk - Feature #7836: Need a way to get Method and UnboundMethod objects to met... Open 02/13/2013
Duplicated by ruby-trunk - Bug #9236: include + include + alias_method + super behaviour incons... Closed 12/10/2013
Duplicated by ruby-trunk - Bug #7993: owner of methods defined after using Module#prepend Closed 03/01/2013

Associated revisions

Revision 44175
Added by Nobuyoshi Nakada 4 months ago

proc.c, vm_method.c: fix super and alias

  • proc.c (method_owner): return the class where alias is defined, not the class original method is defined.
  • vmmethod.c (rbmethodentrymake, rb_alias): store the originally defined class in me. [Bug #7993] [Bug #7842] [Bug #9236]
  • vmmethod.c (rbmethodentrygetwithoutcache): cache included module but not iclass.

History

#1 Updated by Marc-Andre Lafortune about 1 year ago

I agree, this can only be a bug.

#2 Updated by Nobuyoshi Nakada about 1 year ago

Rather I expect [B, A] in this case.

#3 Updated by Yusuke Endoh about 1 year ago

Rather I expect [B, A] in this case.

Fine. I just wanted to point out the weird skipping.
(Actually, I expect nothing for such a code :-)

2013/2/14, SASADA Koichi ko1@atdot.net:

(2013/02/14 16:14), nobu (Nobuyoshi Nakada) wrote:

Rather I expect [B, A] in this case.

+1

// SASADA Koichi at atdot dot net

--
Yusuke Endoh mame@tsg.ne.jp

#4 Updated by Marc-Andre Lafortune about 1 year ago

nobu (Nobuyoshi Nakada) wrote:

Rather I expect [B, A] in this case.

You do?

There would be no way to safely monkey patch this method without using Prepend! So any 1.9.x library that uses monkey patching like aliasmethodchain could be incompatible with prepended classes!

I expect:
B.instancemethod(:m) == B.instancemethod(:m2) # => true in rc2, false in trunk, should be true
B.new.m2 # => [P, B, A], since they are aliases appart from their name

Here is another bug (even more clear) that might be related:
B.instancemethod(:m).owner # => P in rc2 (ok), B in trunk (not ok)
B.instance
method(:m2).owner # => #, should be P

I wish I had time to look at it further.

#5 Updated by Yukihiro Matsumoto about 1 year ago

I expect:

module P
def m; puts "P"; super; end
end
class A
def m; puts "A"; end
end
class B < A
def m; puts "B"; end
alias m2 m
prepend P
alias m3 m
end
B.new.m2
#=> expected: B, A
B.new.m3
#=> expected: P, B, A

Matz.

#6 Updated by Matthew Kerwin about 1 year ago

I'm sorry, but this ticket confuses me. Why does "A" ever get output, if
B#m does not also call super?

#7 Updated by Marc-Andre Lafortune about 1 year ago

phluid61 (Matthew Kerwin) wrote:

I'm sorry, but this ticket confuses me. Why does "A" ever get output, if
B#m does not also call super?

You're right to be confused, there's a missing super in the examples that everyone assumed was there.

So here's the corrected version:

module P
  def m; puts "P"; super; end
end
class A
  def m; puts "A"; end
end
class B < A
  def m; puts "B"; super; end
  alias m2 m
  prepend P
  alias m3 m
end

B.new.m2 #=> expected: B, A
B.new.m3 #=> expected: P, B, A

#8 Updated by Marc-Andre Lafortune about 1 year ago

  • Category set to core
  • Assignee deleted (Yukihiro Matsumoto)

#9 Updated by Koichi Sasada about 1 year ago

  • Assignee set to Nobuyoshi Nakada
  • Target version changed from next minor to 2.1.0

marcandre: why you remove assignee?
you mean specification discussion was finished at #5?
I assume the reason and I assign this ticket nobu, the patch monster.

#10 Updated by Marc-Andre Lafortune about 1 year ago

ko1 (Koichi Sasada) wrote:

marcandre: why you remove assignee?
you mean specification discussion was finished at #5?
I assume the reason and I assign this ticket nobu, the patch monster.

Exactly.

#11 Updated by Nobuyoshi Nakada 4 months ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r44175.
Yusuke, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


proc.c, vm_method.c: fix super and alias

  • proc.c (method_owner): return the class where alias is defined, not the class original method is defined.
  • vmmethod.c (rbmethodentrymake, rb_alias): store the originally defined class in me. [Bug #7993] [Bug #7842] [Bug #9236]
  • vmmethod.c (rbmethodentrygetwithoutcache): cache included module but not iclass.

#12 Updated by Nobuyoshi Nakada 4 months ago

  • Backport set to 1.9.3: DONTNEED, 2.0.0: REQUIRED

#13 Updated by Tomoyuki Chikanaga 3 months ago

  • Backport changed from 1.9.3: DONTNEED, 2.0.0: REQUIRED to 1.9.3: DONTNEED, 2.0.0: DONE

r44175 was already backported to ruby_2_0_0 at r44345.

Also available in: Atom PDF