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 11 years ago
I agree, this can only be a bug.
Updated by nobu (Nobuyoshi Nakada) over 11 years ago
Rather I expect [B, A] in this case.
Updated by mame (Yusuke Endoh) over 11 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 11 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 11 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 11 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 11 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 11 years ago
- Category set to core
- Assignee deleted (
matz (Yukihiro Matsumoto))
Updated by ko1 (Koichi Sasada) over 11 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 11 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 11 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 11 years ago
- Backport set to 1.9.3: DONTNEED, 2.0.0: REQUIRED
Updated by nagachika (Tomoyuki Chikanaga) almost 11 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 10 years ago
- Description updated (diff)
Updated by usa (Usaku NAKAMURA) over 9 years ago
- Related to Bug #11189: alias prepended module added