aboutsummaryrefslogtreecommitdiffstats
path: root/class.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-01-09 14:04:21 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-01-09 14:04:21 +0000
commit140f8b94ced86966fc6979e8cfc5ef3bfa68da5d (patch)
tree307ec78c0a30d97a4049492f867ecab61d02dba2 /class.c
parent347f3f30d6743e8b7cd133ae298c0290f2ef3a1d (diff)
downloadruby-140f8b94ced86966fc6979e8cfc5ef3bfa68da5d.tar.gz
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66764 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'class.c')
-rw-r--r--class.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/class.c b/class.c
index 0b24acd1fc..051632e08c 100644
--- a/class.c
+++ b/class.c
@@ -1174,6 +1174,23 @@ method_entry_i(ID key, VALUE value, void *data)
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, const VALUE *argv, VALUE mod, int obj, int
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();