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);