Bug #7842

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

Added by Yusuke Endoh over 2 years ago. Updated over 1 year ago.

[ruby-core:52206]
Status:Closed
Priority:Normal
Assignee:Nobuyoshi Nakada
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 methods overridden by prepended modules Open 02/13/2013
Related to Ruby trunk - Bug #11189: alias prepended module Open
Duplicated by Ruby trunk - Bug #9236: include + include + alias_method + super behaviour inconsistency between 1.9 and 2.0 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 over 1 year 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.
  • vm_method.c (rb_method_entry_make, rb_alias): store the originally defined class in me. [Bug #7993] [Bug #7842] [Bug #9236]
  • vm_method.c (rb_method_entry_get_without_cache): cache included module but not iclass.

Revision 44175
Added by Nobuyoshi Nakada over 1 year 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.
  • vm_method.c (rb_method_entry_make, rb_alias): store the originally defined class in me. [Bug #7993] [Bug #7842] [Bug #9236]
  • vm_method.c (rb_method_entry_get_without_cache): cache included module but not iclass.

History

#1 Updated by Marc-Andre Lafortune over 2 years ago

I agree, this can only be a bug.

#2 Updated by Nobuyoshi Nakada over 2 years ago

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

#3 Updated by Yusuke Endoh over 2 years 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 over 2 years 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 alias_method_chain could be incompatible with prepended classes!

I expect:
B.instance_method(:m) == B.instance_method(: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.instance_method(: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 over 2 years 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 over 2 years 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 over 2 years 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 over 2 years ago

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

#9 Updated by Koichi Sasada over 2 years 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 over 2 years 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 over 1 year 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.
  • vm_method.c (rb_method_entry_make, rb_alias): store the originally defined class in me. [Bug #7993] [Bug #7842] [Bug #9236]
  • vm_method.c (rb_method_entry_get_without_cache): cache included module but not iclass.

#12 Updated by Nobuyoshi Nakada over 1 year ago

  • Backport set to 1.9.3: DONTNEED, 2.0.0: REQUIRED

#13 Updated by Tomoyuki Chikanaga over 1 year 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.

#14 Updated by Nobuyoshi Nakada over 1 year ago

  • Description updated (diff)

#15 Updated by Usaku NAKAMURA 2 months ago

  • Related to Bug #11189: alias prepended module added

Also available in: Atom PDF