views:

26

answers:

1

OK, real quick, here's the code:

class A
  def foo
    FOO
  end
  def self.foo
    FOO
  end
end
module B
  class C < A

  end
end
B.const_set(:FOO,'asdf')
>> B::C.foo
NameError: uninitialized constant A::FOO
    from ./foo.rb:6:in `foo'
    from (irb):1
>> B.module_eval {FOO='asdf'}
=> "asdf"
>> B::C.foo
=> "asdf"

Aren't they supposed to do the same thing? Why is this happening? At this point, I'm using the module_eval in my code out of necessity, but the const_set seems more readable. Regardless, I'd really like to understand why this happens.

+1  A: 

Your module_eval isn't actually putting the constant in the module. Then, you're just accessing it from main:

module B;end
B.module_eval { FOO = 'asdf' }
>> FOO
=> "asdf"

You can fix that with self::FOO = 'asdf', then it's the same as B.const_set(:FOO,'asdf'). You can also do it more directly like this:

B::FOO = 'asdf'

The main problem with your code is that you can't access constants from other modules like that. If they're in an outer module, you need to specify the scope of the constant with the :: prefix:

def foo
  B::FOO
end
Andrew Vit
Ah, thanks. That explains it. Back to the drawing board :(
Mike