summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2019-07-07 17:58:25 -0700
committerJeremy Evans <code@jeremyevans.net>2019-07-23 09:46:09 -0700
commit9aba971e42c78bb9e446f28c0402bad55147a863 (patch)
tree4fcb7065a00fc0a7306d80df7f1332056920e855
parent11662c70b073da21dcd5213b61434bce2ed6af8f (diff)
Make Object#singleton_methods work correctly for singleton classes of objects
Fixes [Bug #10901]
-rw-r--r--class.c3
-rw-r--r--test/ruby/test_object.rb23
2 files changed, 26 insertions, 0 deletions
diff --git a/class.c b/class.c
index a8d21f9443..243f8c4610 100644
--- a/class.c
+++ b/class.c
@@ -1447,6 +1447,9 @@ rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
int recur = TRUE;
if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
+ if (RB_TYPE_P(obj, T_CLASS) && FL_TEST(obj, FL_SINGLETON)) {
+ rb_singleton_class(obj);
+ }
klass = CLASS_OF(obj);
origin = RCLASS_ORIGIN(klass);
me_arg.list = st_init_numtable();
diff --git a/test/ruby/test_object.rb b/test/ruby/test_object.rb
index 277995b323..fcb6c2826f 100644
--- a/test/ruby/test_object.rb
+++ b/test/ruby/test_object.rb
@@ -865,6 +865,29 @@ class TestObject < Test::Unit::TestCase
assert_match(/@\u{3046}=6\b/, x.inspect)
end
+ def test_singleton_methods
+ assert_equal([], Object.new.singleton_methods)
+ assert_equal([], Object.new.singleton_methods(false))
+ c = Class.new
+ def c.foo; end
+ assert_equal([:foo], c.singleton_methods - [:yaml_tag])
+ assert_equal([:foo], c.singleton_methods(false))
+ assert_equal([], c.singleton_class.singleton_methods(false))
+ c.singleton_class.singleton_class
+ assert_equal([], c.singleton_class.singleton_methods(false))
+
+ o = c.new.singleton_class
+ assert_equal([:foo], o.singleton_methods - [:yaml_tag])
+ assert_equal([], o.singleton_methods(false))
+ o.singleton_class
+ assert_equal([:foo], o.singleton_methods - [:yaml_tag])
+ assert_equal([], o.singleton_methods(false))
+
+ c.extend(Module.new{def bar; end})
+ assert_equal([:bar, :foo], c.singleton_methods.sort - [:yaml_tag])
+ assert_equal([:foo], c.singleton_methods(false))
+ end
+
def test_singleton_class
x = Object.new
xs = class << x; self; end