ruby-changes:54549
From: nobu <ko1@a...>
Date: Wed, 9 Jan 2019 23:04:26 +0900 (JST)
Subject: [ruby-changes:54549] nobu:r66764 (trunk): class.c: refactor class_instance_method_list
nobu 2019-01-09 23:04:21 +0900 (Wed, 09 Jan 2019) New Revision: 66764 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66764 Log: class.c: refactor class_instance_method_list * class.c (class_instance_method_list): gather singleton and extended methods first separately from ancestors. [ruby-core:90872] [Bug #15501] Modified files: trunk/class.c trunk/test/ruby/test_object.rb Index: class.c =================================================================== --- class.c (revision 66763) +++ class.c (revision 66764) @@ -1174,6 +1174,23 @@ method_entry_i(ID key, VALUE value, void https://github.com/ruby/ruby/blob/trunk/class.c#L1174 return ID_TABLE_CONTINUE; } +static void +add_instance_method_list(VALUE mod, struct method_entry_arg *me_arg) +{ + struct rb_id_table *m_tbl = RCLASS_M_TBL(mod); + if (!m_tbl) return; + rb_id_table_foreach(m_tbl, method_entry_i, me_arg); +} + +static bool +particular_class_p(VALUE mod) +{ + if (!mod) return false; + if (FL_TEST(mod, FL_SINGLETON)) return true; + if (BUILTIN_TYPE(mod) == T_ICLASS) return true; + return false; +} + static VALUE class_instance_method_list(int argc, const VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t)) { @@ -1183,17 +1200,23 @@ class_instance_method_list(int argc, con https://github.com/ruby/ruby/blob/trunk/class.c#L1200 if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]); + me_arg.list = st_init_numtable(); + me_arg.recur = recur; + + if (obj) { + for (; particular_class_p(mod); mod = RCLASS_SUPER(mod)) { + add_instance_method_list(mod, &me_arg); + } + } + if (!recur && RCLASS_ORIGIN(mod) != mod) { mod = RCLASS_ORIGIN(mod); prepended = 1; } - me_arg.list = st_init_numtable(); - me_arg.recur = recur; for (; mod; mod = RCLASS_SUPER(mod)) { - if (RCLASS_M_TBL(mod)) rb_id_table_foreach(RCLASS_M_TBL(mod), method_entry_i, &me_arg); + add_instance_method_list(mod, &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(); Index: test/ruby/test_object.rb =================================================================== --- test/ruby/test_object.rb (revision 66763) +++ test/ruby/test_object.rb (revision 66764) @@ -227,6 +227,14 @@ class TestObject < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_object.rb#L227 assert_equal([:foo], o.methods(false), bug8044) end + def test_methods_prepend_singleton + c = Class.new(Module) {private def foo; end} + k = c.new + k.singleton_class + c.module_eval {prepend(Module.new)} + assert_equal([:foo], k.private_methods(false)) + end + def test_instance_variable_get o = Object.new o.instance_eval { @foo = :foo } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/