如何在Ruby中使用C#样式枚举?

时间:2008-10-02 21:36:45

标签: ruby enumeration language-construct

我只想知道在Ruby中模拟C#样式枚举的最佳方法。

5 个答案:

答案 0 :(得分:5)

它并不完全相同,但我会经常为这种事情构建一个哈希:

STATES = {:open => 1, :closed => 2, :max => 3, :min => 4}.freeze()

冻结哈希会阻止我意外修改其内容。

此外,如果您想在访问不存在的内容时引发错误,可以使用defualt Proc来执行此操作:

STATES = Hash.new { |hash, key| raise NameError, "#{key} is not allowed" }
STATES.merge!({:open => 1, :closed => 2, :max => 3, :min => 4}).freeze()

STATES[:other] # raises NameError

答案 1 :(得分:5)

  

具体来说,我希望能够在给定一些变量的情况下对这组值执行逻辑测试。例子是窗口的状态:“最小化,最大化,关闭,打开”

如果你需要枚举映射到值(例如,你需要最小化到等于0,最大化等于100等)我会使用符号哈希值,如下所示:

WINDOW_STATES = { :minimized => 0, :maximized => 100 }.freeze

冻结(就像nate所说)会阻止你在将来意外破坏东西。 您可以通过执行此操作来检查某些内容是否有效

WINDOW_STATES.keys.include?(window_state)

或者,如果您不需要任何值,只需要检查“成员资格”,那么数组就可以了

WINDOW_STATES = [:minimized, :maximized].freeze

像这样使用

WINDOW_STATES.include?(window_state)

如果您的密钥将成为字符串(例如RoR应用程序中的'state'字段),那么您可以使用字符串数组。我在许多rails应用程序中一直这样做。

WINDOW_STATES = %w(minimized maximized open closed).freeze

这就是rails validates_inclusion_of验证器专门用于: - )

个人注意:

我不喜欢打字包括?所有的时间,所以我有这个(由于.in?(1,2,3)的情况,这只是复杂的:

class Object

    # Lets us write array.include?(x) the other way round
    # Also accepts multiple args, so we can do 2.in?( 1,2,3 ) without bothering with arrays
    def in?( *args )
        # if we have 1 arg, and it is a collection, act as if it were passed as a single value, UNLESS we are an array ourselves.
        # The mismatch between checking for respond_to on the args vs checking for self.kind_of?Array is deliberate, otherwise
        # arrays of strings break and ranges don't work right
        args.length == 1 && args.first.respond_to?(:include?) && !self.kind_of?(Array) ?
            args.first.include?( self ) :
            args.include?( self )
        end
    end
end

这可让您输入

window_state.in? WINDOW_STATES

答案 2 :(得分:3)

我不认为Ruby支持真正的枚举 - 但是,仍有可用的解决方案。

Enumerations and Ruby

答案 3 :(得分:3)

在ruby中定义Enum以使用具有常量变量的类的最简单方法。

class WindowState
  Open = 1
  Closed = 2
  Max = 3
  Min = 4
end

答案 4 :(得分:1)

像其他人所说的那样制作类或哈希会起作用。但是,Ruby要做的就是使用symbols。 Ruby中的符号以冒号开头,如下所示:

greetingtype = :hello

它们有点像只包含名称的对象。