diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-01-09 14:04:21 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-01-09 14:04:21 +0000 |
commit | 140f8b94ced86966fc6979e8cfc5ef3bfa68da5d (patch) | |
tree | 307ec78c0a30d97a4049492f867ecab61d02dba2 /class.c | |
parent | 347f3f30d6743e8b7cd133ae298c0290f2ef3a1d (diff) | |
download | ruby-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.c | 31 |
1 files changed, 27 insertions, 4 deletions
@@ -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(); |