2010-11-02 53 views
1

我讀到這篇文章解釋瞭如何使枚舉在Ruby中,還展示瞭如何將它們枚舉,如:我如何將這個基類,它的一個Ruby枚舉

class Blah 

def Blah.add_item(key, value) 
    @hash ||= {} 
    @hash[key] = value 
end 

def Blah.const_missing(key) 
    @hash[key] 
end 

def Blah.each 
    @hash.each {|key, value| yield(key, value)} 
end 

end 
  1. 有我需要的其他枚舉,我可以通過某種方式創建一個基類,因此我不必爲每個方法重複add_item,const_missng和.each方法?

  2. 爲我的所有枚舉創建文件時,我把它放在/lib/enums.rb中,這是一個很好的做法嗎?

  3. 我應該把這個類放到一個模塊裏面嗎,也就是說我相信你是這樣做的嗎?

回答

2
  1. 您可以只使用布拉赫作爲基類。

    C類< Blah; end

    class D < Blah; end

  2. 我想我可能只是將它與每個使用的項目的源代碼放在一起。是的,DIE,DRY和所有這些,但這在線性代碼中最爲重要。將外部軟件與每個項目合併是相當普遍的做法。

  3. 不是。它已經是一個類,所以它只使用一個名稱。將模塊放在使用Blah的代碼中,項目或項目的一部分。這將會很大,而且更需要命名空間。

2

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 
相關問題