Bug #7842
closedAn alias of a "prepend"ed method skips the original method when calling super
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
        
           Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
          Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
          
          
        
        
      
      I agree, this can only be a bug.
        
           Updated by nobu (Nobuyoshi Nakada) over 12 years ago
          Updated by nobu (Nobuyoshi Nakada) over 12 years ago
          
          
        
        
      
      Rather I expect [B, A] in this case.
        
           Updated by mame (Yusuke Endoh) over 12 years ago
          Updated by mame (Yusuke Endoh) over 12 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
        
           Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
          Updated by marcandre (Marc-Andre Lafortune) over 12 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 # => #<B:0x0000010384b418>, should be P
I wish I had time to look at it further.
        
           Updated by matz (Yukihiro Matsumoto) over 12 years ago
          Updated by matz (Yukihiro Matsumoto) over 12 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.
        
           Updated by phluid61 (Matthew Kerwin) over 12 years ago
          Updated by phluid61 (Matthew Kerwin) over 12 years ago
          
          
        
        
      
      I'm sorry, but this ticket confuses me. Why does "A" ever get output, if
B#m does not also call super?
        
           Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
          Updated by marcandre (Marc-Andre Lafortune) over 12 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
        
           Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
          Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
          
          
        
        
      
      - Category set to core
- Assignee deleted (matz (Yukihiro Matsumoto))
        
           Updated by ko1 (Koichi Sasada) over 12 years ago
          Updated by ko1 (Koichi Sasada) over 12 years ago
          
          
        
        
      
      - Assignee set to nobu (Nobuyoshi Nakada)
- Target version changed from 2.6 to 2.1.0
marcandre: why you remove assignee?
you mean specification discussion was finished at [ruby-core:52386]#5?
I assume the reason and I assign this ticket nobu, the patch monster.
        
           Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
          Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
          
          
        
        
      
      ko1 (Koichi Sasada) wrote:
marcandre: why you remove assignee?
you mean specification discussion was finished at [ruby-core:52386]#5?
I assume the reason and I assign this ticket nobu, the patch monster.
Exactly.
        
           Updated by nobu (Nobuyoshi Nakada) almost 12 years ago
          Updated by nobu (Nobuyoshi Nakada) almost 12 years 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 inme. [Bug #7993] [Bug #7842] [Bug #9236]
- 
vm_method.c(rb_method_entry_get_without_cache): cache included
 module but not iclass.
        
           Updated by nobu (Nobuyoshi Nakada) almost 12 years ago
          Updated by nobu (Nobuyoshi Nakada) almost 12 years ago
          
          
        
        
      
      - Backport set to 1.9.3: DONTNEED, 2.0.0: REQUIRED
        
           Updated by nagachika (Tomoyuki Chikanaga) almost 12 years ago
          Updated by nagachika (Tomoyuki Chikanaga) almost 12 years 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.
        
           Updated by nobu (Nobuyoshi Nakada) over 11 years ago
          Updated by nobu (Nobuyoshi Nakada) over 11 years ago
          
          
        
        
      
      - Description updated (diff)
        
           Updated by usa (Usaku NAKAMURA) over 10 years ago
          Updated by usa (Usaku NAKAMURA) over 10 years ago
          
          
        
        
      
      - Related to Bug #11189: alias prepended module added