# Enumerated Types

**URL:** <https://www.ruby-forum.com/t/enumerated-types/84379>\
**Category:** Ruby\
**Created:** [February 3, 2007, 7:53pm UTC](https://www.ruby-forum.com/t/enumerated-types/84379 "2007-02-03T19:53:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ad7895/32.png) [@Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/u/Dan_Stevens_SIAmAI)\
**Post date:** [February 3, 2007, 7:53pm UTC](https://www.ruby-forum.com/t/enumerated-types/84379/1 "2007-02-03T19:53:05Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ad7895/32.png) [@Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/u/Dan_Stevens_SIAmAI)\
**Post date:** [February 3, 2007, 8:01pm UTC](https://www.ruby-forum.com/t/enumerated-types/84379/2 "2007-02-03T20:01:06Z")

</div>

On 03.02.2007 19:52, Dan Stevens (IAmAI) wrote:

> 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.

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 = [  
:old,  
:young,  
:unknown,  
].freeze  
end

HTH

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ad7895/32.png) [@Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/u/Dan_Stevens_SIAmAI)\
**Post date:** [February 5, 2007, 8:55pm UTC](https://www.ruby-forum.com/t/enumerated-types/84379/3 "2007-02-05T20:55:05Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ad7895/32.png) [@Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/u/Dan_Stevens_SIAmAI)\
**Post date:** [February 5, 2007, 9:07pm UTC](https://www.ruby-forum.com/t/enumerated-types/84379/4 "2007-02-05T21:07:07Z")

</div>

On 2/5/07, Dan Stevens (IAmAI) [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> def to\_hex  
> 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?

This is fine. You may want to use a hash to make life simpler though:  
class Color  
HexValues = { :red =\> 0xFF0000, :green =\> 0x00FF00, :blue =\>  
0x0000FF }  
def to\_hex  
HexValues[@color] or @color  
end  
end

---

<div class="post-metadata">

**Author:** ![Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ad7895/32.png) [@Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/u/Dan_Stevens_SIAmAI)\
**Post date:** [February 6, 2007, 9:46pm UTC](https://www.ruby-forum.com/t/enumerated-types/84379/5 "2007-02-06T21:46:10Z")

</div>

On 05.02.2007 20:54, Dan Stevens (IAmAI) wrote:

> case @color  
> 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?

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

---

<div class="post-metadata">

**Author:** ![Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ad7895/32.png) [@Dan\_Stevens\_SIAmAI](https://www.ruby-forum.com/u/Dan_Stevens_SIAmAI)\
**Post date:** [February 6, 2007, 12:34am UTC](https://www.ruby-forum.com/t/enumerated-types/84379/6 "2007-02-06T00:34:35Z")

</div>

On 2/3/07, Dan Stevens (IAmAI) [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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.

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!
