Bug #19270
closedConstants lookup and a singleton class issue
Description
I've noticed that a constant declared in a singleton class may be not visible on an object:
class A
def c; C; end
end
a = A.new
klass = (class << a; self; end)
klass.const_set(:C, 1)
a.c
# (irb):2:in `c': uninitialized constant A::C (NameError)
I would expect that such constant is visible and accessible on an object. It is expected and intentional behaviour?
Updated by nobu (Nobuyoshi Nakada) almost 3 years ago
- Is duplicate of Bug #19269: Constant lookup and #instance_eval added
Updated by alanwu (Alan Wu) almost 3 years ago
It's expected behavior. When you have a singleton class singleton_class.ancestors is:
[singleton_class, attached_object_class, ...]
In this case the lookup for starts at A, which is attached_object_class.
It goes to the right so it never searches singleton_class. The lookup resolves when the
constant is on attached_object_class and it starts at singleton_class:
class A
C = 1
end
a = A.new
klass = (class << a; self; end)
p klass::C # => 1
Updated by Eregon (Benoit Daloze) almost 3 years ago
- Status changed from Open to Closed
@alanwu (Alan Wu) By attached_object_class you mean a.class so A?
Constant lookup behaves lexically, here the scopes around method c are A and top-level/Object.
So here it looks in A, then Object, then ancestors of A. It never looks in subclasses of A (and klass is a subclass of A).