У меня есть простой класс, который определяет некоторые константы, например:
module Foo
class Bar
BAZ = "bof"
...
Все щенки и радуги, пока я не скажу Рейку, чтобы запустить все мои тесты Test::Unit
. Когда это произойдет, я получаю предупреждения:
bar.rb:3: warning: already initialized constant BAZ
Моя привычка заключалась в том, чтобы избежать этих предупреждений, сделав условную инициализацию условной, например:
...
BAZ = "bof" unless const_defined? :BAZ
...
Это, похоже, решает проблему, но это немного утомительно, и я никогда не видел, чтобы кто-то еще инициализировал константы таким образом. Это заставляет меня думать, что я могу делать это неправильно. Есть ли лучший способ инициализировать константы, которые не будут генерировать предупреждения?
Обновить. Посредством немного более подробной информации о том, как я использую эти константы, скажем, я определил класс Token
, который имеет константы для всех символов, которые являются частью синтаксис некоторого искусственного языка. У меня также есть класс Scanner
, который читает поток символов, генерируя экземпляр Token
для каждого из них.
module Foo
class Token
LPAREN = "("
RPAREN = ")"
...
end
class Scanner
def next_token
case read_char()
when Token::LPAREN: # Generate a new LPAREN token
...
То есть, проверяя, какой тип токена должен быть сгенерирован для данного символа, я хочу использовать константы, определенные в Token
.
Обновить 2: Ответ Jörg показал, что проблема, вероятно, заключалась в том, как я конструировал пути в своих операторах require
, а не в как я инициализировал или использовал константы. Я переписал свои операторы require
, чтобы устранить любое создание ручного пути, например:
# File: $PROJECT_ROOT/lib/foo.rb; trying to load $PROJECT_ROOT/lib/foo/bar.rb
require File.expand_path(File.dirname(__FILE__)) + "foo/bar"
теперь записывается, чтобы полагаться на $LOAD_PATH
:
# File: $PROJECT_ROOT/lib/foo.rb; trying to load $PROJECT_ROOT/lib/foo/bar.rb
require 'lib/foo/bar'
Я удалил условные проверки из своих постоянных инструкций инициализации, а rake теперь запускает модульные тесты, не бросая никаких предупреждений.