Ruby Gurus的问题(帮助类似Enum的实现)

时间:2010-12-26 16:36:52

标签: ruby-on-rails ruby

我试图制作一种“枚举”。这是我的实施:

# 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.StatusMyClass1会自动通过对“{1}}的”宏观“调用包含在课程中。

define_enum旨在像Rails中的define_enum调用一样工作。

这可能吗?

2 个答案:

答案 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