Ruby constants have weird behavior in class_eval
I was playing with some code the other day, and I noticed that constants work strangely in class_eval blocks. Sometimes it can find the constant, and sometimes it cannot.
For example, say we have a class with a constant:
class Foo
CONS = 'const'
end
Now, if we reopen the class and print the constant, it works as expected:
>> class Foo
>> puts CONS
>> end
const
However, if we use a class_eval instead of reopening the class, ruby cannot find the constant:
>> Foo.class_eval { puts CONS }
NameError: uninitialized constant CONS
from (irb):12
from (irb):11:in `class_eval'
from (irb):11
It gets even stranger. We can still see the constant in the list of constants:
>> Foo.class_eval { puts self.constants }
CONS
Furthermore, a const_get still works:
>> Foo.class_eval { puts const_get(:CONS) }
const
Finally, if we try the class_eval again with a string instead of a block, it works:
>> Foo.class_eval "puts CONS"
const
Apparently, constants have a problem with blocks inside of class_eval.