Garrison
"Enumerable" is Ruby's way of saying that we can get elements out of a collection, one at a time.
e·nu·mer·ate /i?n(y)o?om??r?t/ Verb:
- Mention (a number of things) one by one.
- Establish the number of.
An "enumerator", then, a the tool we can use to get each element out of a collection in this way. Before we go ahead, it's important to understand what Enumerable
and Enumerator
are in Ruby terms. Let's look at some examples.
First, calling each
on the Array
[4, 8]
in this next example, returns an Enumerator
object.
This is different from how we've been usually using each
.
Enumerable
is a module used as a mixin in the Array
class. It provides a number of enumerators like map
, select
, inject
. The Enumerable
module itself doesn't define the each
method. It's the responsibility of the class that is including this module to do so.
This Array
class, consequently, defines the each
method. It returns an object of the type Enumerator
when no block is given (like our first example). It yields a value of the type self
when there is one (the original array in the next example).
What's the point of returning the Enumerator
then?
Enumerator
is an objectification of enumeration. The point of these methods returning these enumerators is to allow us to chain operations indefinitely and make more heavy-duty collections.
Here we chain the initial each_with_index
enumerator with select
to build an enumerator that returns an array of elements whose values are smaller than their index positions.
map_with_index
on the Array
class through which you can call a block with two arguments: the element and its index. It should return an Enumerator
object if no block is given, an Array
otherwise.
Enumerable
class and learn how and when to make use of these collections.