summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-02-20 14:56:55 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-02-20 14:56:55 +0900
commit0d7f5b8216b88a37407c8885a8fc523e38bff616 (patch)
treebe9da4ed31fd40726558a53847f4cdca7dd5711d
parent8ed15c078b8f953f360034ef003b16a911a6dbbc (diff)
downloadmruby-0d7f5b8216b88a37407c8885a8fc523e38bff616.tar.gz
mruby-0d7f5b8216b88a37407c8885a8fc523e38bff616.zip
metaprog.c: fix a `methods()` bug with `false` argument; fix #5351
-rw-r--r--mrbgems/mruby-metaprog/src/metaprog.c32
-rw-r--r--mrbgems/mruby-metaprog/test/metaprog.rb2
2 files changed, 16 insertions, 18 deletions
diff --git a/mrbgems/mruby-metaprog/src/metaprog.c b/mrbgems/mruby-metaprog/src/metaprog.c
index bd61c9bc6..f2f2e7dda 100644
--- a/mrbgems/mruby-metaprog/src/metaprog.c
+++ b/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)) {
- MRB_CLASS_ORIGIN(klass);
- prepended = TRUE;
+ if (!recur) {
+ if (klass->flags & MRB_FL_CLASS_IS_PREPENDED) {
+ MRB_CLASS_ORIGIN(klass);
+ }
+ method_entry_loop(mrb, klass, set, NULL);
}
+ else {
+ khash_t(st) *undef = kh_init(st, mrb);
- oldklass = 0;
- 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 = NULL;
+ while (klass && (klass != oldklass)) {
+ method_entry_loop(mrb, klass, set, undef);
+ oldklass = klass;
+ klass = klass->super;
}
- 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;
}
diff --git a/mrbgems/mruby-metaprog/test/metaprog.rb b/mrbgems/mruby-metaprog/test/metaprog.rb
index 84f4e00a0..d63913020 100644
--- a/mrbgems/mruby-metaprog/test/metaprog.rb
+++ b/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