The Ruby Enumerable module deserves the top spot in the popularity contest. It packs so many great methods that it’s hard to think of an application that wouldn’t use it.

Since inheritance in Ruby is limited to a single parent class, modules allow you to share functionality between unrelated classes.

Enumerable is such a module. One that you can mix into your classes.

Let’s see for example, what modules are included in the Array , and Hash classes.

Array.included_modules # => [Enumerable, PP::ObjectMixin, Kernel] Hash.included_modules # => [Enumerable, PP::ObjectMixin, Kernel]

Why would you use Enumerable in your class?

The Enumerable module provides you with methods for searching, traversal, and sorting collections.

So if you’re writing something that has to deal with collections, you can just mix in the Enumerable module, and you’re good to go. There’s no need for you to rewrite functionality that you can get for free.

How to make your class Enumerable

So, to use the Enumerable module, you simply include it in your class, and provide an each method that yields each value to a block. That’s it!

class Person attr_accessor :name include Enumerable def initialize(name) @name = name end def each yield name end end Person.new("Cezar").to_a # => ["Cezar"]

You can learn more about attr_accessor if you want.

As you can see in the example above, I don’t have to write the to_a method myself. I can get it for free by including the Enumerable module.

But let’s see something more interesting.

class Person attr_accessor :emails include Enumerable end me = Person.new me.emails = ["home@gmail.com", "work@gmail.com", "newsletters@gmail.com"] me.emails.sort # => ["home@gmail.com", "newsletters@gmail.com", "work@gmail.com"]

Again, I didn’t have to write sort myself. That too comes from the Enumerable module.

Enumerable vs. Enumerator what is the difference?

Even though they look very similar, there is a big difference between the two.

The Enumerable module is the thing you include in your classes to get all the Enumerable methods.

The Enumerator is a class that includes the Enumerable module, just like other classes do. Its purpose is to create enumerable objects that can be chained together.

e = [1, 2, 3].map # => #<Enumerator: ...> e.each_with_index { |n, i| n * i } # => [0, 2, 6]

Another cool thing you can do is call methods on it. For example if you want to get the next element, you can do this.

e = [1, 2, 3].map # => #<Enumerator: ...> e.next # => 1 e.next # => 2

Build your own Enumerable module

What better way to learn what the Ruby Enumerable module does than to create one from scratch.

module Reduceable def reducer(acc) each do |value| acc = yield(acc, value) end acc end end class Person attr_accessor :emails include Reduceable def number_of_emails reducer(0) { |total, email| total + email.size } end def each yield emails end end me = Person.new me.emails = ["home@gmail.com", "work@gmail.com", "newsletters@gmail.com"] me.number_of_emails # => 3

The reducer method receives an initial value as the accumulator ( 0 in this case), and for each value, it passes both the accumulator and the email to the block it was given. Finally, it returns the accumulator.

You can do anything you want with those arguments inside the block. But this example counts the number of emails present in the emails array.

How to find the min/max value

That’s a perfect example of an everyday use case that Enumerable provides.

[1, 2, 3].min # => 1 [1, 2, 3].max # => 3

You can also get more than one value back, by passing a count to min or max .

[1, 2, 3].min(2) # => [1, 2] [1, 2, 3].max(2) # => [3, 2]

How to reset an enumerator

A neat trick you can do with an Enumerator is to rewind it to its first element.

e = [1, 2, 3].map # => #<Enumerator: ...> e.next # => 1 e.next # => 2 e.rewind # => #<Enumerator: ...> e.next # => 1

Reversing an enumerable

There’s a reverse_each method that returns an Enumerator with the elements reversed.

[1, 2, 3].reverse_each.to_a # => [3, 2, 1]

How to remove duplicates enumerable lists

The method you want is called uniq .

[ "a", "a", "b", "b", "c" ].uniq # => ["a", "b", "c"]

Count vs. size vs. length

While size is nothing more than an alias for length , the difference between length and count is that count can take a block. If you pass a block to count , it only counts the number of elements for which the block returns truthy.

[1, :a, "b", nil, false].length # => 5 [1, :a, "b", nil, false].count { |n| n } # => 3

In the example above, 1 , :a , and "a" are all truthy (the are not nil or `false). So the result is 3.

Is $< enumerable?

$< is just an alias for ARGF , and it includes the Enumerable module.

ARGF.class # => ARGF.class ARGF.class.included_modules # => [Enumerable, PP::ObjectMixin, Kernel]