# Idiomatic Ruby: Enumerations

**URL:** <https://www.ruby-forum.com/t/idiomatic-ruby-enumerations/71209>\
**Category:** Ruby\
**Created:** [February 21, 2006, 8:31am UTC](https://www.ruby-forum.com/t/idiomatic-ruby-enumerations/71209 "2006-02-21T08:31:16Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![lstrecv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/e68b1a/32.png) [@lstrecv](https://www.ruby-forum.com/u/lstrecv)\
**Post date:** [February 21, 2006, 8:31am UTC](https://www.ruby-forum.com/t/idiomatic-ruby-enumerations/71209/1 "2006-02-21T08:31:16Z")

</div>

Hi. I’d appreciate comments/criticisms on the following approach &  
code:

For some variables, we need to be able to choose from enumerations.  
For instance, we track different choices on a webform - each has an  
integer code, as well as some other properties. I want to implement a  
class which these are made out of.

How’s this?:

class TimeSlot

```
# Only use predefined
private_class_method :new

# The text description
attr_reader :text

# The integer code
attr_reader :code

      # The legacy_id (key in a legacy database)
attr_reader :legacy_id

def initialize(text, code, legacy_id)
	@text = text
	@code = code
	@legacy_id = legacy_id
end

MORNING = new('morning', 2, 1001)
AFTERNOON = new('morning', 3, 1002)
EVENING = new('evening', 4, 1003)
NIGHT = new('night', 5, 1004')

      # This next line is unDRY, but I'm not sure how to eliminate

```

it.  
# Perhaps instead of just listing the constansts, use a  
register\_value method which both defines the constant  
# and adds it to the @@values - but I’m not sure how to  
implement this  
@@members = [MORNING, AFTERNOON, EVENING, NIGHT]

```
def self.from_code(c)
	@@members.find { |t| t.code == c } || raise ArgumentError, "No

```

TimeSlot has code #{c}"  
end

end

Also - we have several of these - how would I extract a common  
Enumeration mixin? I’d like to be able to include Enumeration, much as  
you include Singleton, to turn a class into an enumeration type along  
these lines.

---

<div class="post-metadata">

**Author:** ![lstrecv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/e68b1a/32.png) [@lstrecv](https://www.ruby-forum.com/u/lstrecv)\
**Post date:** [February 21, 2006, 10:50am UTC](https://www.ruby-forum.com/t/idiomatic-ruby-enumerations/71209/2 "2006-02-21T10:50:07Z")

</div>

removed\_email\_address@domain.invalid wrote:

> class TimeSlot  
> # The legacy\_id (key in a legacy database)  
> EVENING = new(‘evening’, 4, 1003)  
> NIGHT = new(‘night’, 5, 1004’)
> 
> ```
> # This next line is unDRY, but I'm not sure how to eliminate
> 
> ```
> 
> it.  
> # Perhaps instead of just listing the constansts, use a  
> register\_value method which both defines the constant  
> # and adds it to the @@values - but I’m not sure how to  
> implement this  
> @@members = [MORNING, AFTERNOON, EVENING, NIGHT]

I would not use a class variable here as it does not seem needed. A  
simple  
class member will be sufficient. As for the definition method:

def self.enum(\*a)  
c = new(\*a).freeze  
(@members || = []) \<\< c  
c  
end

Then you can do

MORNING = enum ‘morning’, 2, 1001

OTOH, you do not need this at all. You can simply use  
TimeSlot.constants to  
get all constants defined in this class. If you need to be more  
selective  
(foe example if you define nested classes in this class) you can do

def self.enums  
constants.select {|x| self === x}  
end

Which will select only instances of TimeSlot.

> along these lines.  
> I think I’ve seen an enumeration module on RAA. If not it will be quite  
> easy to put some code in a module and implement YourModule#included or  
> YourModule#extended to make certain changes (like making new private).  
> HTH

Kind regards

```
robert
```
