[Bug #2395] 可視性の変更による alias されたメソッドの無効化

Bug #2395: e$B2D;k@-$NJQ99$K$h$ke(B alias e$B$5$l$?%a%=%C%I$NL58z2=e(B
http://redmine.ruby-lang.org/issues/show/2395

e$B5/I<<Te(B: _ wanabe
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Low
e$B%+%F%4%je(B: core
ruby -v: ruby 1.9.2dev (2009-11-21 trunk 25882) [i386-mingw32], ruby
1.8.8dev (2009-11-24 revision 25892) [i386-mingw32]

alias e$B$5$l$?85$N%a%=%C%I$re(B undef e$B$9$k$H$-!e(Balias
e$B$NA0$K2D;k@-$rJQ99$9$k=hM}$,$$k$He(B
e$B$^$?85$KLa$7$F$be(B alias e$B@h$N%a%=%C%I$,8F$Y$J$/$J$j$^$9!#e(B
rb_export_method() e$BCf$Ne(B rb_add_method()
e$B$K$h$k8=>]$N$h$&$G$9!#e(B

$ cat test.rb
class Foo
def foo
p :foo
end
class Bar0 < Foo
alias bar foo
end
class Bar1 < Foo
private :foo
public :foo
alias bar foo
end
undef foo

Bar0.new.bar
Bar1.new.bar
end

$ ruby19/ruby -v test.rb
ruby 1.9.2dev (2009-11-21 trunk 25882) [i386-mingw32]
:foo
test.rb:16:in <class:Foo>': undefined method bar for
#Foo::Bar1:0xb90a48 (NoMethodError)
from test.rb:1:in `

$ ruby18/ruby -v test.rb
ruby 1.8.8dev (2009-11-24 revision 25892) [i386-mingw32]
:foo
test.rb:16:in bar': super: no superclass method foo for
#Foo::Bar1:0x28a4f78 (NoMethodError)
from test.rb:16

e$B1sF#$G$9!#e(B

2009e$BG/e(B11e$B7ne(B24e$BF|e(B11:29 _ wanabe [email protected]:

alias e$B$5$l$?85$N%a%=%C%I$re(B undef e$B$9$k$H$-!e(Balias e$B$NA0$K2D;k@-$rJQ99$9$k=hM}$,$$k$He(B
e$B$^$?85$KLa$7$F$be(B alias e$B@h$N%a%=%C%I$,8F$Y$J$/$J$j$^$9!#e(B
rb_export_method() e$BCf$Ne(B rb_add_method() e$B$K$h$k8=>]$N$h$&$G$9!#e(B

e$B4q6x$J$3$H$K!"F1$8%?%$%_%s%0$G$[$\F1$8LdBj$KG:$s$G$$$^$7$?!#e(B

$ ruby19 -e public :eval; alias foo eval; foo p 1
-e:1:in <main>': undefined method foo for main:Object
(NoMethodError)

wanabe e$B$5$s$NDs5/$7$F$$$kLdBj$Oe(B 2 e$B$D$KJ,$1$i$l$k$H;W$$$^$9!#e(B

  1. bar e$B$,e(B foo e$B$Ne(B alias e$B$G!"e(Bfoo e$B$,e(B ZSUPER
    e$B$@$C$?:]!e(Bfoo e$B$G$O$J$/e(B bar e$B$re(B
    e$BC5$7$F$7$^$&e(B (1.9 e$B$@$1!;d$,G:$s$G$$$?$N$O$3$C$Ae(B)

class C
private
def foo; FOO; end
def bar; BAR; end
end
class D < C
public :foo
alias bar foo
end
p D.new.public_send(:bar) #=> BAR

send e$B$@$H:GE,2=$G@5$7$/F0$$$F$7$^$&!"e(Bpublic_send

e$B$@$HH/>I$9$ke(B

  1. e$BF1$8%/%i%9$Ge(B alias
    e$B$r:n$C$?$i%a%=%C%I<BBN$N<BBN$,%3%T!<$5$l$k$N$Ke(B
    e$B7Q>5@h$Ge(B alias e$B$r:n$C$?$i<BBN$O%3%T!<$5$l$J$$e(B (1.8
    e$B$be(B 1.9 e$B$be(B)

class C
private
def foo; foo; end
alias bar foo
public :bar
end
class D < C
public :foo
alias baz foo
end
class C
undef foo
end
p D.new.bar #=> foo
p D.new.baz #=> NoMethodError

  1. e$B$Oe(B 1.9 e$B$N%P%0$@$H;W$$$^$9!#%Q%C%A$r$D$1$^$9e(B
    (e$B$?$@$7$^$@%F%9%He(B
    e$B$7$F$^$;$se(B) e$B!#e(B2)
    e$B$O;EMM$+$I$&$+J9$+$J$$$H$o$+$j$^$;$s!#e(B

Index: vm_eval.c

vm_eval.c (revision 25898)
+++ vm_eval.c (working copy)
@@ -105,6 +105,7 @@
}
case VM_METHOD_TYPE_ZSUPER: {
klass = RCLASS_SUPER(klass);

  • id = me->def->original_id;
    if (!klass || !(me = rb_method_entry(klass, id))) {
    return method_missing(recv, id, argc, argv, NOEX_SUPER);
    }
    Index: vm_insnhelper.c
    ===================================================================
    vm_insnhelper.c (revision 25898)
    +++ vm_insnhelper.c (working copy)
    @@ -548,6 +548,7 @@
    }
    case VM_METHOD_TYPE_ZSUPER:{
    VALUE klass = RCLASS_SUPER(me->klass);

  • id = me->def->original_id;
    me = rb_method_entry(klass, id);

    if (me != 0) {

e$B1sF#$G$9!#e(B

2009e$BG/e(B11e$B7ne(B24e$BF|e(B12:55 Yusuke ENDOH [email protected]:

public :foo
alias baz foo
end
class C
undef foo
end
p D.new.bar #=> foo
p D.new.baz #=> NoMethodError

(snip)

  1. e$B$O;EMM$+$I$&$+J9$+$J$$$H$o$+$j$^$;$s!#e(B

e$B$3$C$A$O4V0c$$$G$7$?!#e(Bpublic e$B$de(B private e$B$r30$9$H!"e(B1.8
e$B$G$be(B 1.9 e$B$G$be(B

class C
def foo; foo; end
alias bar foo
end
class D < C
alias baz foo
end
class C
undef foo
end
p D.new.bar #=> foo
p D.new.baz #=> foo

e$B$HLdBj$J$/F0$/$N$G!"$d$O$j2D;k@-$b$+$i$s$@LdBj$G$9$M!#e(B

e$B%9!<%Q!<%/%i%9$N%a%=%C%I$Ne(B public/private e$B$re(B ZSUPER
e$B$G<BAu$9$k$3$H$,e(B
e$B860x$@$H;W$$$^$9$,!"$I$&D>$7$?$b$N$G$7$g$&$M!#e(BZSUPER e$B$re(B
alias e$B$9$k;~$Oe(B
e$B%a%=%C%I<BBN$rJ#@=$9$k!)e(B

e$B1sF#$G$9!#e(B

2009e$BG/e(B11e$B7ne(B24e$BF|e(B13:09 Yusuke ENDOH [email protected]:

e$B%9!<%Q!<%/%i%9$N%a%=%C%I$Ne(B public/private e$B$re(B ZSUPER e$B$G<BAu$9$k$3$H$,e(B
e$B860x$@$H;W$$$^$9$,!"$I$&D>$7$?$b$N$G$7$g$&$M!#e(BZSUPER e$B$re(B alias e$B$9$k;~$Oe(B
e$B%a%=%C%I<BBN$rJ#@=$9$k!)e(B

e$B$3$C$A$r<BAu$7$^$7$?!#e(B
[ruby-dev:39760] e$B$N%3!<%I$@$He(B :foo, :foo
e$B$H=PNO$9$k$h$&$K$J$j$^$9!#e(B

e$B$3$N%Q%C%A$rEv$F$k$He(B original_id e$B$H0c$&L>A0$Ne(B ZSUPER
e$B$J%a%=%C%I$OH/@8e(B
e$B$7F@$J$/$J$k$O$:$J$N$G!"e(B[ruby-dev:39761]
e$B$N%Q%C%A$OITMW$K$J$j$^$9!#e(B

make check
e$B$G$b%(%i!<$OA}$($J$+$C$?$N$G!"H?BP0U8+$,L5$1$l$P%3%_%C%He(B
e$B$7$h$&$H;W$$$^$9!#e(B

diff --git a/vm_method.c b/vm_method.c
index 215db503b86713 100644
a/vm_method.c
+++ b/vm_method.c
@@ -858,7 +858,9 @@ rb_method_definition_eq(const
rb_method_definition_t *d1, const rb_method_defini
void
rb_alias(VALUE klass, ID name, ID def)
{

  • VALUE target_klass = klass;
    rb_method_entry_t *orig_me;

  • rb_method_flag_t flag = NOEX_UNDEF;

    if (NIL_P(klass)) {
    rb_raise(rb_eTypeError, no class to make alias);
    @@ -869,6 +871,7 @@ rb_alias(VALUE klass, ID name, ID def)
    rb_secure(4);
    }

  • again:
    orig_me = search_method(klass, def);

    if (UNDEFINED_METHOD_ENTRY_P(orig_me)) {
    @@ -877,8 +880,15 @@ rb_alias(VALUE klass, ID name, ID def)
    rb_print_undef(klass, def, 0);
    }
    }

  • if (orig_me->def->type == VM_METHOD_TYPE_ZSUPER) {

  • klass = RCLASS_SUPER(klass);

  • def = orig_me->def->original_id;

  • flag = orig_me->flag;

  • goto again;

  • }

  • rb_add_method_me(klass, name, orig_me, orig_me->flag);
  • if (flag == NOEX_UNDEF) flag = orig_me->flag;
  • rb_add_method_me(target_klass, name, orig_me, flag);
    }

/*

e$B1sF#$G$9!#e(B

2010e$BG/e(B1e$B7ne(B13e$BF|e(B21:13 wanabe [email protected]:

e$B$7$h$&$H;W$$$^$9!#e(B

e$B$9$$^$;$s!"$3$N7o$I$&$J$j$^$7$?$G$7$g$&$+!#e(B
e$B:9$7;Y$($J$1$l$P%3%
%C%H$7$F$$$?$@$1$k$H$"$j$,$?$$$G$9!#e(B

e$B$9$C$+$jK:$l$F$$$?$s$G$9$,e(B (e$B$9$$^$;$se(B)
e$B!"@hF|%3%
%C%H$7$^$7$?e(B (r26255)e$B!#e(B

e$B%o%J%Y$H?=$7$^$9!#e(B

09/11/24 Yusuke ENDOH [email protected]:

2009e$BG/e(B11e$B7ne(B24e$BF|e(B13:09 Yusuke ENDOH [email protected]:

e$B%9!<%Q!<%/%i%9$N%a%=%C%I$Ne(B public/private e$B$re(B ZSUPER e$B$G<BAu$9$k$3$H$,e(B
e$B860x$@$H;W$$$^$9$,!"$I$&D>$7$?$b$N$G$7$g$&$M!#e(BZSUPER e$B$re(B alias e$B$9$k;~$Oe(B
e$B%a%=%C%I<BBN$rJ#@=$9$k!)e(B

e$B$3$C$A$r<BAu$7$^$7$?!#e(B
[ruby-dev:39760] e$B$N%3!<%I$@$He(B :foo, :foo e$B$H=PNO$9$k$h$&$K$J$j$^$9!#e(B
e$B!JCfN,!Ke(B
make check e$B$G$b%(%i!<$OA}$($J$+$C$?$N$G!"H?BP0U8+$,L5$1$l$P%3%_%C%He(B
e$B$7$h$&$H;W$$$^$9!#e(B

e$B$9$$^$;$s!"$3$N7o$I$&$J$j$^$7$?$G$7$g$&$+!#e(B
e$B:9$7;Y$($J$1$l$P%3%
%C%H$7$F$$$?$@$1$k$H$"$j$,$?$$$G$9!#e(B

e$B%A%1%C%He(B #2395 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B

r26255

http://redmine.ruby-lang.org/issues/show/2395