Вопрос по ruby – Доступ к константе

6

Почему я не могу получить доступ к B? в последующем от "A"; а может из основного окружения?

module A; end
A.instance_eval{B=1}

B #=> 1
A::B #=> uninitialized
@ JoshLee41 Ruby1.9.3 sawa

Ваш Ответ

4   ответа
4

документацияinstance_eval (выделение мое):

Evaluates a string containing Ruby source code, or the given block, within the context of the receiver (obj). In order to set the context, the variable self is set to obj while the code is executing, giving the code access to obj’s instance variables.

Здесь больше ничего не делается. В частности, константное присвоение выполняется в окружающем контексте блока. Заметим:

irb(main):001:0> module A
irb(main):002:1>   module B; end
irb(main):003:1>   B.instance_eval { C = 1 }
irb(main):004:1> end
=> 1
irb(main):006:0> A::C
=> 1
3

 A.const_set(:B, 1)
 A::B #=> 1

Что касается того, почему это не работает, в Ruby 1.8 и 1.9.2+ (в 1.9.1 это было не так), постоянный поиск ограничен лексической областью. Я нашел хорошийСообщение блога с объяснением. Цитировать:

Note that these rules apply to constant definition as well as lookup. In 1.8 and 1.9.2, a constant defined in a class_evaluated block will be defined in the enclosing lexical scope, rather than the scope of the receiver.

То же самое относится и кinstance_eval.

Спасибо, это очень помогло. sawa
4
Because . . .

альную область видимости.

Для определения константы важна лексическая область действия, а не текущий получатель или значениеself.

1
module A; end
A.class_eval{B=1}
B # Undefined
A::B # 1

почему это работает, я не совсем уверен. Я иногда использую метапрограммирование таким образом, когда создаю очень мета-фреймворки, такие как Малый Собственный Коллайдер, но не в повседневной работе.

Я попробовал это на 1.9.1. Извините, что не упомянул об этом, я не ожидал, что он изменится между крошечными версиями.
Это интересно. Тогда как жеinstance_eval работа в 1.9.1? Это как я сообщил? sawa
Вау, это сложно. Я хотел бы, чтобы кто-то спросил об этом на сайте Ruby. sawa
@sawa ОбаB а такжеA::B не определены.
Ты уверен в этом? Насколько я тестировал на irb 1.9.3, он дает тот же результат, что и сinstance_eval. sawa

Похожие вопросы