Enumerated Types

Discussion in 'Ruby' started by Dan Stevens (IAmAI), Feb 3, 2007.

  1. As part of a solution, I wish the value of an attribute to be one of a
    finite set of values, in other words I believe I want an 'enumerated
    type'. I've look at the 'Enumerable' and 'Enumerator' class and they
    appear to me to be unrelated to what I wish to achieve (correct me if
    I'm wrong).

    I could do the traditional method of named constants with integer
    values but I can't help feeling that there must be a class or some
    nice method of doing this. Any advice would be appreciated.
     
    Dan Stevens (IAmAI), Feb 3, 2007
    #1
    1. Advertisements

  2. I believe there are enum classes in the RAA. If you do not want to use
    them, symbols come pretty close:

    class YourClass
    YOUR_ENUM = [
    :eek:ld,
    :young,
    :unknown,
    ].freeze
    end

    HTH

    Kind regards

    robert
     
    Robert Klemme, Feb 3, 2007
    #2
    1. Advertisements

  3. It seems to me that I should simply be able to use symbols as values
    for my enumerated types, like for example:

    class Color

    def initialize(color)
    @color = color
    end

    def to_hex
    case @color
    when :red: 0xFF0000
    when :green: 0x00FF00
    when :blue: 0x0000FF
    else @color
    end
    end

    end

    c = Color.new:)red)
    puts c.to_hex.to_s(16)

    Might there be any reason why I shouldn't do this, or am I quite fine
    doing this?


     
    Dan Stevens (IAmAI), Feb 5, 2007
    #3
  4. I picked up this snippet of code:

    # -------+---------+---------+-------- + --------+---------+---------+---------+
    # Add methods enum and bit_enum to the Object class, thus making it much
    # easier and less error-prone to define a long list of constants in a
    # class. This idea comes from Ara.T.Howard@noaa, in a posting to ruby-talk
    # on August 2, 2005 (in reply to a question). These work very nicely with
    # a word-list array as generated via %w(). Very clever!
    #
    class Object
    def enum_constants(*list)
    mc = Module === self ? self : self.class
    list.flatten.each_with_index{|e, i| mc.const_set e.to_s.intern, i}
    end
    def enum_bit_constants(*list)
    mc = Module === self ? self : self.class
    list.flatten.each_with_index{|e, i| mc.const_set e.to_s.intern, 2 ** i}
    end
    end
    # -------+---------+---------+-------- + --------+---------+---------+---------+

    An example of using it:

    # Constants that define all categories of packets which we recognize.
    enum_constants %w(
    SBC_NONE SBC_ARRAY SBC_NONUSER SBC_NO_IDSTR
    SBC_IGNFAIL SBC_ALL
    SBC_UNMATCHED )

    The difference between enum_constants() and enum_bit_constants is
    that enum_constants will define the values as 1, 2, 3, 4, 5, etc, while
    enum_bit_constants will define them as 1,2,4,8,16,32. You can 'or'
    the enum_bit_constant values together, and each one is a separate
    bit so it won't clobber any other bit constant.

    If you are not used to the %w() method of quoting, note that you only
    put the names you want in there. You do *not* separate them with
    commas!
     
    Garance A Drosehn, Feb 5, 2007
    #4
  5. That's perfectly ok. If you need your enums only for mapping then I'd
    probably do this:

    Color = Struct.new :name do
    CODES = Hash.new {|h,k| k}.update(
    :red => 0xFF0000,
    :green => 0x00FF00
    # ...
    )

    def to_hex; CODES[name] end
    end

    irb(main):010:0> Color.new:)red).to_hex.to_s 16
    => "ff0000"

    If you need more enum dependent behavior you might want put more complex
    objects into the hash instead of only Fixnums.

    Kind regards

    robert
     
    Robert Klemme, Feb 6, 2007
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.