---
title: enum VS enum VS enum - Enumeration, Enumerator & Enumerable
teaser: How do enums works in Ruby, and what they actually are.
tags: enum,enumerable,enumerator,enumeration,design pattern,postgresql,ruby,development
author: Fernando Marques
published_on: 2022-10-04
---

During my apprenticeship at thoughtbot, I was asked by my mentor, [Matheus Richard](https://thoughtbot.com/blog/authors/matheus-richard), the following question: *"Do you know what enumerators are?"* and I promptly replied: *"Yes! Enums are basically a collection of options!"*. And well, that was when my world fell apart - apparently, there are "3 types of enums". But don't worry, at least they are correlated!!

## So, what about enum?

In Rails, when we say `enum`, we are essentially referring to the [Rails' `ActiveRecord::Enum` class](https://api.rubyonrails.org/v5.1.7/classes/ActiveRecord/Enum.html).
Since ActiveRecord is Rails' ORM to communicate with its Database (normally Postgres!), it is also correlated to [PostgreSQL's `Enumerated type`](https://www.postgresql.org/docs/current/datatype-enum.html). It's worth mentioning that we can rely purely on Rails' `enum` and just create an `integer` column in the database and let Rails handle the rest. Their biggest advantage is that they have the readability of a `string` column while keeping the efficiency and the simplicity of an `integer` column in the actual Database!

> **Important:** `enum` is a way to refer to the Rails' `ActiveRecord::Enum` class unambiguously and should be the prefered word.

So a good way of answering the question "What is an `enum`?" is:
> "`enum` is the Rails' solution to work with collections of data in our Database."

This is what an `enum` looks like in Rails:

```rb
# Here we have an Article Model that can be either a draft,
# a published article, or an archived article.
class Article < ApplicationRecord
  enum status: { draft: 0, published: 1, archived: 2 }
end

# Using enums gives us access to methods based on the Enumerations created:
article = Article.new(status: :draft)

article.draft?
# => true

article.published!
# This will change the status from draft to published

article.published?
# => true

article.draft?
# => false
```

## Enumeration

Enumeration in **plain english** is the act of counting out or listing items. It works over a **collection of elements**. It is worth mentioning that Enumeration is a *concept*.

Different programming languages might have different definitions of an Enumeration. For instance, Ruby does **not** have a definition for Enumeration.

So please remember that Enumeration is **not** a Ruby class or class. It's a concept that is often used in *other* programming languages, as opposed to enumerators and enumerables, which are present and defined in Ruby.

## Enumerator

Now that we know what enumeration is, we can disclose what an [`enumerator` is](https://ruby-doc.org/core-3.1.2/Enumerator.html). In Ruby, `enumerator` is how we traverse collections. You are most likely already familiar with one of its most popular method: `#each`! Quoting [Scout APM](https://scoutapm.com/blog/ruby-enumerator):

> "The enumerator is a basic implementation of the iterator design pattern – so it allows the environment to access the list of items in a class without exposing other details (such as its implementation)."

To add to our conversation and to the previous quoting, I'll quote [Joël Quenneville](https://thoughtbot.com/blog/authors/joel-quenneville):
> There are two iterator design patterns:
>
> - *Internal iteration* where the collection handles the traversal itself and calls a block you pass such as with traditional calls to the `#each` method
> - *External iteration* where the calling code controls the traversal by manually calling `#next` or `#cycle`
>
> Enumerator has both `#each`, `#next`, and `#cycle` methods so it implements both patterns
>
> For more on this idea, *Design Patterns in Ruby* chapter 7 covers internal/external iterator patterns.

When we previously used the `#each` method in the example above, we were using it in its block form,
where the elements are evaluated individually in the Enumeration.

Now, to better visualize it, instead of passing a block, let's call the `#each` in a non-block form:

```rb
enum = [1, 2].each

puts enum
# => #<Enumerator:0x00005560a80557e0>
# The #each method returns an instance of enumerator!!
# And it's wrapping the iteration!

# Here we are doing an external iteration
enum = [1, 2].cycle

puts enum.next
# => 1

puts enum.next
# => 2

puts enum.next
# => 1

puts enum.next
# => 2
# Notice how we can create an infinite series of elements from our Array!
```

This allows us to have more control than the `#each` method,
especially when dealing with scenarios where we don't want to iterate through every element immediately.

Here we have two great use cases from [Joël](https://thoughtbot.com/blog/authors/joel-quenneville) of when he had to create an `enumerator`:

- [Modeling a Paginated API as a Lazy Stream](https://thoughtbot.com/blog/modeling-a-paginated-api-as-a-lazy-stream)
- [Lazy Refactoring](https://thoughtbot.com/blog/lazy-refactoring)

But honestly, for us to manually build/write an `enumerator`, especially in a Rails app, is a somewhat rare occasion.
Most of the time we will be using a collection's implementation of `#each` or methods from the `enumerable` module. We rarely interact with instances of the enumerator class.

## Enumerable

And finally, here is where the Ruby magic happens...

Popular methods such as `#any?`, `#filter`, and `#reduce` are methods from the `enumerable` module. Most of the methods we have in `Hashes` and `Arrays` are actually from it, and they both can be considered `enumerables`, as they inherit the module.

Basically, this is [Ruby's solution](https://ruby-doc.org/core-3.1.2/Enumerable.html)
to make and to allow the developer to make a class enumerated, as in having an Enumeration.

Thinking in plain English, codes aside:

- The suffix `able` means *"capable of, fit for, or worthy"*.
- In this case, we could say that it *"is capable of enumerating"*.

*"Capable of enumerating"*...? As an Enumeration? Yes! That is right!

```rb
my_friends_professions = {
  "Jane" => "Software Engineer",
  "Merelyn" => "Born rich, sorry!"
  "Anthony" => "Designer",
}

# Here we are traversing the hash, iterating by it.
my_friends_professions.each do |key, value|
  puts "#{key} is a(n) #{value}"
end
# => "Jane is a(n) Software Engineer",
# => "Merelyn is a(n) Born rich, sorry!"
# => "Anthony is a(n) Designer",

# Here we are also traversing the Hash, to sort it.
my_friends_professions.sort
# => "Anthony is a(n) Designer",
# => "Jane is a(n) Software Engineer",
# => "Merelyn is a(n) Born rich, sorry!"

# And lastly, we are also traversing it to verify
# if the Hash has any pair of key/value.
my_friends_professions.none?
# => false
```

## Let's Recap what we've learned

To sum it all up in the most straightforward way as possible, We're going to summarize it in 4 lines:

1. In a Rails context, `enum` refers to `ActiveRecord::Enum`.
2. Enumeration is the concept of traversing over or being traversible. Keep in mind that this is not a ruby concept!
3. `Enumerable` is a ruby class that provides access to most of the methods used by an Enumeration.
4. `Enumerator` is a ruby class that allows an `enumerable` to be iterated over. The best example is the `each` method.

And that's it! Congratulations for reading that far!

Suddenly "enum" don't sound so scary anymore, right?!

## References

- [Rails Docs - ActiveRecord::Enum](https://api.rubyonrails.org/v7.0.4/classes/ActiveRecord/Enum.html)
- [Ruby Docs - Enumerator class](https://ruby-doc.org/core-3.1.2/Enumerator.html)
- [Ruby Docs - Enumerable module](https://ruby-doc.org/core-3.1.2/Enumerable.html)
- [Scout APM - How (and Why) to use Ruby Enumerators](https://scoutapm.com/blog/ruby-enumerator)
- [PostgreSQL - Enumerated datatypes](https://www.postgresql.org/docs/current/datatype-enum.html)
- [Refactoring Guru - Iterator design pattern](https://refactoring.guru/design-patterns/iterator)
