I have this code:
class A
def print
puts CONSTANT
end
end
module B
CONSTANT = "Don't Panic!"
end
Suppose a
is an instance of class A.
So I need a definition of CONSTANT
that should be able to be found to make a.print
available.
I considered to include the module B
into a
's singleton class like:
a.singleton_class.send :include, B
a.print # error: CONSTANT isn't found
I assumed it should be okay now to call the method but actually not.
The constant should be successfully imported as the following code works as expectation:
a.singleton_class.constants # => [.., :CONSTANT, ..]
However, by including the constant into the class instead of singleton class, it works:
a.class.send :include, B
a.print # prints: Don't Panic!
I thought it is strange that I can't refer a constant that is defined in a singleton class. If this is reasonable, I want to know why.
The class returned by singleton_class
is an anonymous class which was inherited from class of the object a
.
So a.class
and a.singleton_class
refer to different objects.
puts a.class.object_id # => 79495930
puts a.singleton_class.object_id # => 79495830
And also different classes: a.singleton_class
is a child class of A
.
a.singleton_class.superclass # => A
a.singleton_class.ancestors # => [B, A, Object, Kernel, BasicObject]
a.class.ancestors # => [A, Object, Kernel, BasicObject]
And because of this, a.singleton_class
doesn't share its own constants to parent just like any other child class do.
puts a.class.constants # => []
puts a.singleton_class.constants # => [:CONSTANT]