Why does Ruby class_eval remove constants from scope?

I created a class with a constant and a method:

class A
  FOO = 'hello'
  def bar
    puts FOO
  end
end

A.new.bar
=> 'hello'

And everything works as expected. However, when I do this:

A.class_eval do
  def bar
    puts FOO
  end
end

A.new.bar
NameError: uninitialized constant FOO

Strange ... To get around this, I do:

A.class_eval do
  def bar
    puts self.class::FOO
  end
end

Any good explanation why this is so?

+4
source share
1 answer

Constants are viewed

  • outward in the ads of lexically spanning modules
  • up in the inheritance chain of the current module declaration

So let's just do what Ruby does:

  • look in lexically closed module declarations: easy - no module declarations
  • : , ... ? , , , class Object - Object FOO, Kernel BasicObject.

: . FOO. FOO , .

[API Ruby reflection , : # 1 Module.nesting, # 2 () Module.nesting.first.ancestors.]

: , module_eval ? , ! , , , . .

, : , , instance_eval , , , module_eval . , String , Module.nesting , , !

+5

All Articles