summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/ruby/test_variable.rb28
-rw-r--r--variable.c6
2 files changed, 34 insertions, 0 deletions
diff --git a/test/ruby/test_variable.rb b/test/ruby/test_variable.rb
index aa301f2bc7..f14b4019df 100644
--- a/test/ruby/test_variable.rb
+++ b/test/ruby/test_variable.rb
@@ -35,6 +35,34 @@ class TestVariable < Test::Unit::TestCase
end
end
+ def test_singleton_class_included_class_variable
+ c = Class.new
+ c.extend(Olympians)
+ assert_empty(c.singleton_class.class_variables)
+ assert_raise(NameError){ c.singleton_class.class_variable_get(:@@rule) }
+ c.class_variable_set(:@@foo, 1)
+ assert_equal([:@@foo], c.singleton_class.class_variables)
+ assert_equal(1, c.singleton_class.class_variable_get(:@@foo))
+
+ c = Class.new
+ c.extend(Olympians)
+ sc = Class.new(c)
+ assert_empty(sc.singleton_class.class_variables)
+ assert_raise(NameError){ sc.singleton_class.class_variable_get(:@@rule) }
+ c.class_variable_set(:@@foo, 1)
+ assert_equal([:@@foo], sc.singleton_class.class_variables)
+ assert_equal(1, sc.singleton_class.class_variable_get(:@@foo))
+
+ c = Class.new
+ o = c.new
+ o.extend(Olympians)
+ assert_equal([:@@rule], o.singleton_class.class_variables)
+ assert_equal("Zeus", o.singleton_class.class_variable_get(:@@rule))
+ c.class_variable_set(:@@foo, 1)
+ assert_equal([:@@foo, :@@rule], o.singleton_class.class_variables.sort)
+ assert_equal(1, o.singleton_class.class_variable_get(:@@foo))
+ end
+
def test_variable
assert_instance_of(Integer, $$)
diff --git a/variable.c b/variable.c
index f3d73fac63..1627467bd9 100644
--- a/variable.c
+++ b/variable.c
@@ -3209,6 +3209,12 @@ static void*
mod_cvar_of(VALUE mod, void *data)
{
VALUE tmp = mod;
+ if (FL_TEST(mod, FL_SINGLETON)) {
+ if (rb_namespace_p(rb_ivar_get(mod, id__attached__))) {
+ data = mod_cvar_at(tmp, data);
+ tmp = cvar_front_klass(tmp);
+ }
+ }
for (;;) {
data = mod_cvar_at(tmp, data);
tmp = RCLASS_SUPER(tmp);