Ответ DigitalRoss хороший.Я представлю альтернативу.Предположим, вы хотите, чтобы все ваши перечисления жили в модуле.Все, что вам нужно, это маленький модуль перечисления, например:
module Enumeration
include Enumerable
def self.included(m)
m.extend self
end
def each(&block)
constants.find_all do |name|
name =~ /^[A-Z_\d]+$/
end.map do |name|
[name, const_get(name)]
end.sort_by(&:last).each(&block)
end
end
Когда вам нужно перечисление, создайте для него модуль, включите Enumeration
и определите ваши ключи и значения как константы со всеми заглавными буквамиnames.
module States
include Enumeration
INIT = 1
RUN = 2
DONE = 3
end
Модуль ответит на любой из методов, предоставленных Enumerable
:
p States.to_a
# => [["INIT", 1], ["RUN", 2], ["DONE", 3]]
Вы можете обнаружить, что иногда вам все равно, какие значения есть,просто они разные.Давайте добавим в Enumeration метод value
, который упрощает создание констант с автоматически увеличивающимися ключами:
module Enumeration
def value(name, value = next_value)
const_set(name, value)
end
def next_value
(map(&:last).max || 0) + 1
end
end
Теперь давайте рассмотрим несколько планет:
module Planets
include Enumeration
value :MERCURY
value :VENUS
value :EARTH
end
p Planets.to_a
# => [["MERCURY", 1], ["VENUS", 2], ["EARTH", 3]]
Конечно, этиперечисления - это просто коллекции нормальных констант, поэтому вы можете использовать их напрямую:
p Planets::MERCURY # => 1