mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Fix Module#class_variables for singleton classes of classes/modules
Module#class_variables should reflect class variable lookup. For singleton classes of classes/modules, this means the lookup should be: * Singleton Class * Class * All Ancestors of Class Note that this doesn't include modules included in the singleton class, because class variable lookup doesn't include those. Singleton classes of other objects do not have this behavior and always just search all ancestors of the singleton class, so do not change the behavior for them. Fixes [Bug #8297]
This commit is contained in:
parent
5cb283217b
commit
7470f96565
Notes:
git
2019-09-22 08:10:54 +09:00
2 changed files with 34 additions and 0 deletions
|
@ -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, $$)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue