metaprog.c: fix a `methods()` bug with `false` argument; fix #5351

parent 8ed15c07
...@@ -207,39 +207,35 @@ method_entry_loop(mrb_state *mrb, struct RClass *klass, khash_t(st) *set, khash_ ...@@ -207,39 +207,35 @@ method_entry_loop(mrb_state *mrb, struct RClass *klass, khash_t(st) *set, khash_
static mrb_value static mrb_value
mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *klass) mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *klass)
{ {
khint_t i;
mrb_value ary; mrb_value ary;
mrb_bool prepended = FALSE;
struct RClass *oldklass; struct RClass *oldklass;
khash_t(st) *set = kh_init(st, mrb); khash_t(st) *set = kh_init(st, mrb);
khash_t(st) *undef = (recur ? kh_init(st, mrb) : NULL);
if (!recur && (klass->flags & MRB_FL_CLASS_IS_PREPENDED)) { if (!recur) {
MRB_CLASS_ORIGIN(klass); if (klass->flags & MRB_FL_CLASS_IS_PREPENDED) {
prepended = TRUE; MRB_CLASS_ORIGIN(klass);
}
method_entry_loop(mrb, klass, set, NULL);
} }
else {
khash_t(st) *undef = kh_init(st, mrb);
oldklass = 0; oldklass = NULL;
while (klass && (klass != oldklass)) { while (klass && (klass != oldklass)) {
method_entry_loop(mrb, klass, set, undef); method_entry_loop(mrb, klass, set, undef);
if ((klass->tt == MRB_TT_ICLASS && !prepended) || oldklass = klass;
(klass->tt == MRB_TT_SCLASS)) { klass = klass->super;
}
else {
if (!recur) break;
} }
oldklass = klass; kh_destroy(st, mrb, undef);
klass = klass->super;
} }
ary = mrb_ary_new_capa(mrb, kh_size(set)); ary = mrb_ary_new_capa(mrb, kh_size(set));
for (i=0;i<kh_end(set);i++) { for (khint_t i=0; i<kh_end(set); i++) {
if (kh_exist(set, i)) { if (kh_exist(set, i)) {
mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i))); mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));
} }
} }
kh_destroy(st, mrb, set); kh_destroy(st, mrb, set);
if (undef) kh_destroy(st, mrb, undef);
return ary; return ary;
} }
......
...@@ -64,6 +64,8 @@ end ...@@ -64,6 +64,8 @@ end
assert('Kernel#methods', '15.3.1.3.31') do assert('Kernel#methods', '15.3.1.3.31') do
assert_equal Array, methods.class assert_equal Array, methods.class
assert_equal [:foo], Class.new{def self.foo; end}.methods(false)
assert_equal [], Class.new{}.methods(false)
end end
assert('Kernel#private_methods', '15.3.1.3.36') do assert('Kernel#private_methods', '15.3.1.3.36') do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment