我试图制作一种“枚举”。这是我的实施:
# 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"
因此,上面@@status
中定义的self.Status
和MyClass1
会自动通过对“{1}}的”宏观“调用包含在课程中。
define_enum
旨在像Rails中的define_enum
调用一样工作。
这可能吗?
答案 0 :(得分: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
)和类变量@@my_var
。
答案 1 :(得分:1)
请注意:http://code.dblock.org/ShowPost.aspx?id=184(略微改善http://www.rubyfleebie.com/enumerations-and-ruby/)。让您写下以下内容。
class Gender
include Enum
Gender.define :MALE, "male"
Gender.define :FEMALE, "female"
end
当然
Gender.all
Gender::MALE