By the end of this talk, developers should be able to:
- Define “list” and give two examples of lists in Ruby.
- Diagram the flow of Enumerable methods as invoked through concrete classes.
- Give two examples of methods defined in Enumerable and available on all three of Range, Array, and Hash.
- Fork and clone this repository. FAQ
- Create a new branch,
training
, for your work. - Checkout to the
training
branch. - Install dependencies with
npm install
.
A list is an abstract data type (ADT) that represents an ordered list of items. The list may be empty. If not empty, the list has a first item followed by a list containing the rest of the items. This is not a rigorous definition.
Enumerable is Ruby's implementation of the list
abstraction.
What are some types of lists? Let's brainstorm.
What are some things we'd put on those lists?
In JavaScript, the concept of list is built into Array. In Ruby, it is built into Enumerable which is included in Ruby's Array.
The following table contains a mapping of some of the methods that potentially touch all the elements in an Array. We've already covered most of these in Ruby Array Methods.
JavaScript | Ruby |
---|---|
every |
all? |
filter |
select |
forEach |
each |
map |
map |
reduce |
reduce |
some |
any? |
But, wait. Where is the method all?
defined? The method reduce
? They're
from the Enumerable
mix-in, and will be the focus of this talk. "Enumerable"
is another word for "iteratable", so we can say that each of Ruby's Array
,
Range
, and Hash
types behave as something that can be iterated-over.
Ruby's Enumerable module
provides many list processing methods relying on a class's each
method.
Ruby's Array class includes the Enumerable module.
In Ruby, modules serve two purposes. The first is to create name spaces. The second is to supply common behavior to a class.
The Math
module hides mathematical functions inside the name-space Math
so
that short and common names don't pollute the global name-space (e.g.
Math::PI
or Math.cos
).
The Enumerable
module contains code implementing list methods in terms of a
concrete class's each
method.
Let's diagram the delegation from Array to Enumerable and back.
Ruby's Range class provides a convenient way to express a sequence of integers. Range includes Enumerable so we can treat instances as a list.
rng = 1..10
Let's explore using Range as an enumerable in bin/range_list.rb
.
In bin/range_lab.rb
, use reduce
to calculate the sum of all the even
numbers in a Range. All the odd numbers. Now use each_with_object
to do both
at once.
Hint: Better Hash Injection using each_with_object
Hash includes Enumerable so we can treat it as a list.
h = {}
Let's explore using Hash as an enumerable in bin/hash_list.rb
.
In bin/hash_lab.rb
, use reduce
to accumulate all of the keys and values in
a Hash as Arrays. Store these keys and values in a memo Hash with the keys
:keys
and :values
. Now use each_with_object
to do the same.
Run the linter after you complete the reduce
task. Notice a curious linter
warning? Fix all the rest, then continue.
Two images to give you a sense of the relationships in Ruby.
These images may diverge slightly from the actual relationships, Ruby is an evolving language, but do give a sense of much of what goes on.
- All content is licensed under a CCBYNCSA 4.0 license.
- All software code is licensed under GNU GPLv3. For commercial use or alternative licensing, please contact legal@ga.co.