metaprog.c: fix a `methods()` bug with `false` argument; fix
MODIFY
mrbgems/mruby-metaprog/src/metaprog.c
mrbgems/mruby-metaprog/src/metaprog.c
@@ -207,39 +207,35 @@ method_entry_loop(mrb_state *mrb, struct RClass *klass, khash_t(st) *set, khash_
static mrb_value
mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *klass)
{
- khint_t i;
mrb_value ary;
- mrb_bool prepended = FALSE;
struct RClass *oldklass;
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) {
+ if (klass->flags & MRB_FL_CLASS_IS_PREPENDED) {
MRB_CLASS_ORIGIN(klass);
- prepended = TRUE;
}
+ method_entry_loop(mrb, klass, set, NULL);
+ }
+ else {
+ khash_t(st) *undef = kh_init(st, mrb);
- oldklass = 0;
+ oldklass = NULL;
while (klass && (klass != oldklass)) {
method_entry_loop(mrb, klass, set, undef);
- if ((klass->tt == MRB_TT_ICLASS && !prepended) ||
- (klass->tt == MRB_TT_SCLASS)) {
- }
- else {
- if (!recur) break;
- }
oldklass = klass;
klass = klass->super;
}
+ kh_destroy(st, mrb, undef);
+ }
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)) {
mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));
}
}
kh_destroy(st, mrb, set);
- if (undef) kh_destroy(st, mrb, undef);
return ary;
}

MODIFY
mrbgems/mruby-metaprog/test/metaprog.rb
mrbgems/mruby-metaprog/test/metaprog.rb
@@ -64,6 +64,8 @@ end
assert('Kernel#methods', '15.3.1.3.31') do
assert_equal Array, methods.class
+ assert_equal [:foo], Class.new{def self.foo; end}.methods(false)
+ assert_equal [], Class.new{}.methods(false)
end
assert('Kernel#private_methods', '15.3.1.3.36') do

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