[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]