Module#const_set和Module#module_eval之间的区别

时间:2010-10-01 04:15:04

标签: ruby module metaprogramming

他们不应该做同样的事吗?为什么会这样?此时,我在代码中使用module_eval是必要的,但const_set似乎更具可读性。无论如何,我真的很想知道为什么会这样。

这是代码:

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"

1 个答案:

答案 0 :(得分:2)

您的module_eval实际上并未将常量放入模块中。然后,您只需从main访问它:

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

您可以使用self::FOO = 'asdf'修复此问题,然后它与B.const_set(:FOO,'asdf')相同。您也可以直接这样做:

B::FOO = 'asdf'

您的代码的主要问题是您无法从其他模块访问常量。如果它们位于外部模块中,则需要使用::前缀指定常量的范围:

def foo
  B::FOO
end