ruby-changes:37412
From: shugo <ko1@a...>
Date: Wed, 4 Feb 2015 16:45:35 +0900 (JST)
Subject: [ruby-changes:37412] shugo:r49493 (trunk): * class.c (method_entry_i, class_instance_method_list,
shugo 2015-02-04 16:45:29 +0900 (Wed, 04 Feb 2015) New Revision: 49493 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=49493 Log: * class.c (method_entry_i, class_instance_method_list, rb_obj_singleton_methods): should not include methods of superclasses if recur is false. [ruby-dev:48854] [Bug #10826] Modified files: trunk/ChangeLog trunk/class.c trunk/test/ruby/test_refinement.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 49492) +++ ChangeLog (revision 49493) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Feb 4 15:34:25 2015 Shugo Maeda <shugo@r...> + + * class.c (method_entry_i, class_instance_method_list, + rb_obj_singleton_methods): should not include methods of + superclasses if recur is false. [ruby-dev:48854] [Bug #10826] + Wed Feb 4 16:32:40 2015 Matt Hoyle <matt@d...> * ext/bigdecimal/bigdecimal.c (VpSetPTR): fix a typo, 'expoennt' Index: class.c =================================================================== --- class.c (revision 49492) +++ class.c (revision 49493) @@ -1125,25 +1125,32 @@ ins_methods_pub_i(st_data_t name, st_dat https://github.com/ruby/ruby/blob/trunk/class.c#L1125 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC); } +struct method_entry_arg { + st_table *list; + int recur; +}; + static int method_entry_i(st_data_t key, st_data_t value, st_data_t data) { const rb_method_entry_t *me = (const rb_method_entry_t *)value; - st_table *list = (st_table *)data; + struct method_entry_arg *arg = (struct method_entry_arg *)data; long type; if (me && me->def->type == VM_METHOD_TYPE_REFINED) { + VALUE klass = me->klass; me = rb_resolve_refined_method(Qnil, me, NULL); if (!me) return ST_CONTINUE; + if (!arg->recur && me->klass != klass) return ST_CONTINUE; } - if (!st_lookup(list, key, 0)) { + if (!st_lookup(arg->list, key, 0)) { if (UNDEFINED_METHOD_ENTRY_P(me)) { type = -1; /* none */ } else { type = VISI(me->flag); } - st_add_direct(list, key, type); + st_add_direct(arg->list, key, type); } return ST_CONTINUE; } @@ -1153,7 +1160,7 @@ class_instance_method_list(int argc, con https://github.com/ruby/ruby/blob/trunk/class.c#L1160 { VALUE ary; int recur, prepended = 0; - st_table *list; + struct method_entry_arg me_arg; if (argc == 0) { recur = TRUE; @@ -1169,16 +1176,17 @@ class_instance_method_list(int argc, con https://github.com/ruby/ruby/blob/trunk/class.c#L1176 prepended = 1; } - list = st_init_numtable(); + me_arg.list = st_init_numtable(); + me_arg.recur = recur; for (; mod; mod = RCLASS_SUPER(mod)) { - if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list); + if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)&me_arg); if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue; if (obj && FL_TEST(mod, FL_SINGLETON)) continue; if (!recur) break; } ary = rb_ary_new(); - st_foreach(list, func, ary); - st_free_table(list); + st_foreach(me_arg.list, func, ary); + st_free_table(me_arg.list); return ary; } @@ -1391,7 +1399,8 @@ VALUE https://github.com/ruby/ruby/blob/trunk/class.c#L1399 rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj) { VALUE recur, ary, klass, origin; - st_table *list, *mtbl; + struct method_entry_arg me_arg; + st_table *mtbl; if (argc == 0) { recur = Qtrue; @@ -1401,22 +1410,23 @@ rb_obj_singleton_methods(int argc, const https://github.com/ruby/ruby/blob/trunk/class.c#L1410 } klass = CLASS_OF(obj); origin = RCLASS_ORIGIN(klass); - list = st_init_numtable(); + me_arg.list = st_init_numtable(); + me_arg.recur = recur; if (klass && FL_TEST(klass, FL_SINGLETON)) { if ((mtbl = RCLASS_M_TBL(origin)) != 0) - st_foreach(mtbl, method_entry_i, (st_data_t)list); + st_foreach(mtbl, method_entry_i, (st_data_t)&me_arg); klass = RCLASS_SUPER(klass); } if (RTEST(recur)) { while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) { if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0) - st_foreach(mtbl, method_entry_i, (st_data_t)list); + st_foreach(mtbl, method_entry_i, (st_data_t)&me_arg); klass = RCLASS_SUPER(klass); } } ary = rb_ary_new(); - st_foreach(list, ins_methods_i, ary); - st_free_table(list); + st_foreach(me_arg.list, ins_methods_i, ary); + st_free_table(me_arg.list); return ary; } Index: test/ruby/test_refinement.rb =================================================================== --- test/ruby/test_refinement.rb (revision 49492) +++ test/ruby/test_refinement.rb (revision 49493) @@ -1362,6 +1362,31 @@ class TestRefinement < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L1362 end; end + module NotIncludeSuperclassMethod + class X + def foo + end + end + + class Y < X + end + + module Bar + refine Y do + def foo + end + end + end + end + + def test_instance_methods_not_include_superclass_method + bug10826 = '[ruby-dev:48854] [Bug #10826]' + assert_not_include(NotIncludeSuperclassMethod::Y.instance_methods(false), + :foo, bug10826) + assert_include(NotIncludeSuperclassMethod::Y.instance_methods(true), + :foo, bug10826) + end + private def eval_using(mod, s) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/