2010-12-26 19 views
1

"enum"のようなものを作ろうとしています。ここに私の実装です:Ruby Gurusに関する質問(Enumのような実装に役立つ)

# Format of input hash to AnEnum::initialize is : 
# { 
# Symbol => [Fixnum => String] 
# } 
# Example: 
# { 
# :active => [1 => "Active"] 
# } 

class AnEnum 
    @@values = nil 
    def initialize(hash) 
    @@values = hash 
    end 

    def values 
    @@values 
    end 

    def [](symbol) 
    values[symbol][0] # return the number for the symbol. e.g. 1 
    end 

    def text(symbol) 
    values[symbol][1] # return the text for the symbol. e.g. "Active" 
    end 
end 

使用例:

class MyClass1 

    @@status = AnEnum.new({ 
     :open => [1, 'Active'], 
     :closed => [2, 'Closed'] 
    }) 

    def self.Status 
    @@status 
    end  

end 

# test it (it works!) 

MyClass1.Status[:open] # => 1 
MyClass1.Status.text(:open) # => "Active" 

これは動作しますが、私はそれがより多くの「エレガント」と「ダイナミック」にしたい:

AnEnumを定義することが可能ですMyClass2のように:

class MyClass2 
    define_enum "Status", :as => { 
    :open => [1, 'Active'], 
    :closed => [2, 'Closed'] 
    } 
end 

これらが動作するように:

MyClass2.Status[:open] # => 1 
MyClass2.Status.text(:open) # => "Active" 

したがって、上記MyClass1で定義さ@@statusself.Statusが自動的define_enumに呼び出す様「マクロ」によってクラスに含まれます。

define_enumは、たとえばbefore_filter Railsでの呼び出しのように機能するように意図されています。

これは可能ですか?

+0

"Rubyの達人のための質問" の部分は、任意の有用な情報を提供していません。タグは、それがルビーであることを示しているので、SOのすべてが質問でなければならず、あなたはガウスが役に立たないだけでいいと言っています。 –

答えて

1

あなたが実際にこの機能を必要としているため、あなた自身の利益のためにこの問題に取り組んでいるなら、それは素晴らしいことですが、既にこれを行う沢山のRubyの宝石があります。それぞれの「州」に異なる行動が必要な場合は、classy_enumという便利な宝石を書いています。それ以外の場合はhere are a ton of othersです。

あなたの質問に答えるには、あなたが記述しているように、クラスメソッドまたはマクロを追加することは間違いありません。あなたのクラスに続いて

module MyEnum 
    def define_enum(name, states) 
    ... meta code here ... 
    end 
end 

:ハイレベルの概要は次のようになり、それはあなたがやろうとしているかに応じて、トリッキー取得する場所

MyClass 
    extend MyEnum 

    define_enum :name, :state1 => [], :state2 => [] 
end 

「メタコードは」です。あなたがこのルートに行くつもりなら、他の人たちが最初にやったことをチェックすることをお勧めします。例では、大文字のメソッド名(def self.Status)やクラス変数など、ちょっと変わったものがいくつかあります。

関連する問題