I’ve never been a big fan of modern art. Some pieces are so abstract that I don’t really get the point – and I know I’m not the only one.
But in programming, abstraction is different. It makes for more eloquent and productive code by concealing complexity. Let’s witness abstraction by stepping through 3 related methods:
each
, collect
& select
.
The each
method:
1 2 3 4 5 6 7 8 9 |
|
The each
method iterates through individual elements in the array and returns the original array untouched.
When I first learned the each
method, I used it almost exclusively when working with arrays to make the computer do alot of the leg work for me.
Abraham Maslow explains this consequence:
…if all you have is a hammer, everything looks like a nail.
However, since the each
method does not change the original array, I started writing alot of code that looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Here, I am creating a new empty array, just so I can shovel items into it with the each
method. If this feels bulky to you, that’s because it is! Programmers might say this pattern reeks of code smell.
The ruby collect
method is a better tool for the job, and it is just an abstraction of the each
method.
Here is collect
using the example from above:
1 2 3 4 5 6 7 8 9 |
|
Note that the collect
method returns a new array which I have set equal to “odds_and_ends.”
But what if we only wanted to return a part of the array if it matches certain criteria? In that case, collect
no longer the best option.
As you might have guessed, the ruby select
method is an abstraction of the collect
method. It also returns a new array, with an implicit if clause built in.
Continuing with our example…
If we were to use collect
, it would return a messy array including nil values…
1 2 3 4 5 6 7 |
|
…while select
gets the job done more cleanly. It uses the implicit if to return only values matching the specified logic:
1 2 3 4 5 |
|
So remember, abstraction is your friend!
To recap: select
is an abstraction of collect
which is just an abstraction of each
. Use them to freshen up any and all code smell. I’m still working to make sure I choose the right methods.
By the way, if you were wondering where the each
method comes from, you would be right to assume it is just another abstraction of simpler ruby properties! In a future blog post, I will go over how all of these iteration methods break down using the yield
statement.