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
,並定義鍵和值與所有大寫名稱的常量。
module States
include Enumeration
INIT = 1
RUN = 2
DONE = 3
end
模塊將任何由Enumerable
提供的方法作出迴應:
p States.to_a
# => [["INIT", 1], ["RUN", 2], ["DONE", 3]]
你可能會發現你有時候不關心的值,只是他們是不同的。讓我們增加枚舉的方法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