Разница между модулем # const_set и модулем # module_eval - PullRequest
3 голосов
/ 01 октября 2010

Разве они не должны делать то же самое?Почему это происходит?На данный момент я использую 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 Ответ

2 голосов
/ 01 октября 2010

Ваш module_eval на самом деле не помещает константу в модуль.Затем вы просто получаете к нему доступ из основного:

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
...