Stop including Enumerable, return Enumerator instead

Many times I have seen people including Enumerable module into their
classes. But I cannot stop thinking that in many cases having methods
such as each_with_index
or take_while or
minmax and many others
that are available in Enumerable are not
core responsibility of the class that is including them itself.

In such case I prefer to go Java-way and provide external Enumerator for
those who need to call one of the many useful Enumerable methods on the
collection. I think that we need to ask ourselves a question: Is that class a
collection?. If it really is then it absolutely makes sense to
include Enumerable. If however it is not a collection, but rather a class
which happens contain something else, or providing a collection,
well then maybe external Enumerator is your solution.

Standard library

If you call the most famous Array#each method without a block, you will see that
you get an enumerator in the response.

Therfore whenever you see an example using one of them, you can just substitue
it with the other.

#to_enum & #enum_for

What can #to_enum & #enum_for do for you? Well, they can create the
Enumerator based on any method which yields arguments. Usually
the convention is to create the Enumerator based on method #each
(no surprise here).

Why?

Of course returning Enumerator makes most sense when returning collection (such as Array)
would be inconvinient or impossible due to performance reasons, like
IO#each_byte or
IO#each_char.

What do you need to remember?

Not much actually. Whenever your method yields values, just use #to_enum
(or #enum_for as you already know there are identical) to create
Enumerator based on the method itself, if block code is not provided.
Sounds complicated? It is not. Have a look at the example.

We are working in super startup having milions of users. And thousands of them can
have gravatar. We would prefer not to return them all in an array right? No problem.
Thanks to our magic oneliner return enum_for(:each) unless block_given? we can
share the collection without computing all the data.

This might be really usefull, especially when the caller does not need to have it all: