# Newbie question: Enumerators

**URL:** <https://www.ruby-forum.com/t/newbie-question-enumerators/179312>\
**Category:** Ruby\
**Created:** [November 21, 2009, 10:36pm UTC](https://www.ruby-forum.com/t/newbie-question-enumerators/179312 "2009-11-21T22:36:21Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![omran\_n](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/bc79bd/32.png) [@omran\_n](https://www.ruby-forum.com/u/omran_n)\
**Post date:** [November 21, 2009, 10:36pm UTC](https://www.ruby-forum.com/t/newbie-question-enumerators/179312/1 "2009-11-21T22:36:21Z")

</div>

Hi, I know this is a very newbie question but its one concept that  
despite google and the O’Riley book I cant get my head around.

Can someone please give a simple explantion of what exactly an  
Enumerator is, what it can act on and why you can pass ‘array.to\_enum’  
to a method that expect ‘array’? What sort of objects can be defined as  
‘enumerable’ and what makes them so? What is the difference between and  
Enumerator and an Iterator?

Thanks in advance.

Imran Nazir

Imran’s profile" border=“0”\>  
Friend, Boho, House Owner, Citizen, Engineer

---

<div class="post-metadata">

**Author:** ![omran\_n](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/bc79bd/32.png) [@omran\_n](https://www.ruby-forum.com/u/omran_n)\
**Post date:** [November 21, 2009, 11:00pm UTC](https://www.ruby-forum.com/t/newbie-question-enumerators/179312/2 "2009-11-21T23:00:21Z")

</div>

Hi –

On Sun, 22 Nov 2009, Omran N. wrote:

> Hi, I know this is a very newbie question but its one concept that  
> despite google and the O’Riley book I cant get my head around.

It isn’t a very nuby question at all. Enumerators are a pretty  
advanced topic!

> Can someone please give a simple explantion of what exactly an  
> Enumerator is, what it can act on and why you can pass  
> ‘array.to\_enum’ to a method that expect ‘array’? What sort of  
> objects can be defined as ‘enumerable’ and what makes them so? What  
> is the difference between and Enumerator and an Iterator?

An Enumerator is an Enumerable object (it has all the Enumerable  
methods, like map, inject, find, etc.). The difference between an  
enumerator and most enumerable objects is that most enumerable objects  
have a “natural” solution to the question of what items they are  
enumerating (or iterating over). For an array, the natural solution is  
that the items are the elements of the array. For a hash, it’s the  
key/value pairs, and so on.

An enumerator knows about the Enumerable methods, but it doesn’t have  
any natural or automatic sense of what to iterate through. Therefore,  
it has to attach itself to another object – in fact, to a specific  
method on another object.

Once you hook an enumerator up to a method on another object, the  
enumerator will perform all of its enumerable operations (map, find,  
etc.) by drawing on the output from that method.

Here’s a kind of artificial example that might show you the basic  
workings:

class MyDemo  
def yield\_stuff  
yield 1  
yield 22  
yield 333  
yield 4444  
end  
end

md = MyDemo.new  
e = md.to\_enum(:yield\_stuff)

p e.select {|x| x \> 100 } # [333, 4444]

If you rename yield\_stuff to each, and create the enumerator like  
this:

e = md.to\_enum

it will still work, because the default method the enumerator attaches  
to is each.

Note that I would be able to pass my enumerator to any method that  
expected an enumerable object, on which it could call select and other  
enumerable methods.

I don’t think I’ve answered everything but hopefully that will get you  
started.

David

---

<div class="post-metadata">

**Author:** ![omran\_n](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/bc79bd/32.png) [@omran\_n](https://www.ruby-forum.com/u/omran_n)\
**Post date:** [November 21, 2009, 11:20pm UTC](https://www.ruby-forum.com/t/newbie-question-enumerators/179312/3 "2009-11-21T23:20:15Z")

</div>

On Saturday 21 November 2009 03:35:03 pm Omran N. wrote:

> Hi, I know this is a very newbie question but its one concept that despite  
> google and the O’Riley book I cant get my head around.
> 
> Can someone please give a simple explantion of what exactly an Enumerator  
> is,

Something which provides several things you usually find in an  
Enumerable  
object, such as #each. Probably the simplest example of why you would  
want one  
is to take something that behaves like #each and use other fun tools  
like  
#map. A useless example – you already know what map does:

(1…10).map{|x| x\*2}

Now you can combine it with other iterators:

(1…10).each\_slice(2).map{|a,b| a+b}

If you want to see what each\_slice is doing, try this:

(1…10).each\_slice(2).to\_a

Basically, each\_slice is returning an enumerator which, instead of just  
giving  
us the numbers 1-10, it gives us the pairs of numbers – 1,2; then 3,4;  
and so  
on.

You can do other fun (but pointless) hacks like:

10.times.map{|x|x+1} == (1…10).to\_a

Another reason you would want one is the ability to call enum.next  
repeatedly  
– to invert control, in a way. That is, rather than doing this:

File.open(‘foo’) do |file|  
file.each\_line do |line|  
# do something with line  
end  
end

You could instead do this:

File.open(‘foo’) do |file|  
enum = file.each\_line  
begin  
loop do  
line = enum.next  
# do something with line  
end  
rescue StopIteration  
# end of file  
end  
end

Why would you want to? Well, in case you wanted to do those reads out of  
order  
– basically, it lets you control when and how you read a line. Here’s  
an  
example that’s closer to being practical:

File.open(‘foo’) do |file|  
enum = file.each\_line  
begin  
loop do  
line = enum.next.chomp  
while line =~ /\$/  
line = line.chop + enum.next.chomp  
end  
# do something with line…  
end  
rescue StopIteration  
# end of file  
end  
end

Basically, this looks for any line that ends in a backslash and treats  
that as  
a continued line. But for that to work, we’re essentially having to read  
ahead  
– notice that second “enum.next” in there. File#each\_line won’t work,  
but a  
technique like this might be useful to implement, say,  
File#each\_continued\_line.

> what it can act on

Anything that has an #each method, or any method that behaves similarly.  
Look  
up the documentation for Object#enum\_for for an example. In fact, these  
days,  
whenever I write any sort of iterator, I make sure to return an enum if  
I  
don’t get a block. That’s how the above each\_line works.

> and why you can pass ‘array.to\_enum’ to a method  
> that expect ‘array’?

Most methods don’t “expect” any particular type at all, probably only a  
behavior. I don’t know what method you’re talking about, but they  
probably  
just expect something that implements ‘each’.

Google “duck typing” for more on this philosophy.

By the way, I may have told you _way_ more than you ever wanted to know,  
as  
there’s absolutely no reason for passing ‘array.to\_enum’ to a method  
that  
would’ve been happy with ‘array’, because ‘array.to\_enum.each’ does  
exactly  
the same thing as ‘array.each’, only slightly less efficiently.

> What sort of objects can be defined as ‘enumerable’  
> and what makes them so?

Well, again, see duck typing. There’s nothing special about making an  
object  
“enumerable”. The easiest way to do so is to include the Enumerable  
module,  
but no sane code would ever check that – if needed, you could rewrite  
everything Enumerable does.

For a semi-formal definition, look up the documentation for that  
Enumerable  
module. Anything that includes that module can probably be considered  
Enumerable. Anything that behaves like that module is by definition  
Enumerable.

Note that the Enumerator class uses Enumerable.

> What is the difference between and Enumerator and  
> an Iterator?

I’m not sure what an iterator is. I’m guessing it’s meant to be a method  
like  
each. Call it with a block, and it runs the block on each element of  
itself.  
Call it without a block, and it returns an Enumerator for itself.

Unless the word “iterator” is being used a lot, I wouldn’t worry too  
much. I  
only see it once in the definition – iterator? is an alias for  
block\_given?

---

<div class="post-metadata">

**Author:** ![omran\_n](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/bc79bd/32.png) [@omran\_n](https://www.ruby-forum.com/u/omran_n)\
**Post date:** [November 22, 2009, 11:02pm UTC](https://www.ruby-forum.com/t/newbie-question-enumerators/179312/4 "2009-11-22T23:02:11Z")

</div>

Omran N. wrote:

> What sort of objects can be defined as  
> ‘enumerable’ and what makes them so?

Something is enumerable if it implements a method (conventionally called  
“each”) which yields a series of values into a block. If you mix in the  
Enumerable module then you get a whole bunch of additional methods which  
build on this - select, map, min/max, sort\_by etc. Each of those method  
just calls your “each” method and then processes the values yielded.

> Can someone please give a simple explantion of what exactly an  
> Enumerator is, what it can act on and why you can pass ‘array.to\_enum’  
> to a method that expect ‘array’?

As it happens, someone asked me to write this up a few days ago. The  
result is here:  
[http://wiki.github.com/rdp/ruby\_tutorials\_core/enumerator](http://wiki.github.com/rdp/ruby_tutorials_core/enumerator)

It’s not something that most people need. The most common use is when  
you want to use the Enumerable methods but iterate using a method other  
than ‘each’, for example ‘each\_byte’ or ‘each\_with\_index’

---

<div class="post-metadata">

**Author:** ![omran\_n](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/bc79bd/32.png) [@omran\_n](https://www.ruby-forum.com/u/omran_n)\
**Post date:** [November 23, 2009, 12:31am UTC](https://www.ruby-forum.com/t/newbie-question-enumerators/179312/5 "2009-11-23T00:31:19Z")

</div>

Thanx for responses, you guys are champions!

Imran Nazir

Friend, Boho, House Owner, Citizen, Engineer

* * *

From: Omran N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
To: ruby-talk ML [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Sent: Sat, 21 November, 2009 21:35:03  
Subject: Newbie question: Enumerators

Hi, I know this is a very newbie question but its one concept that  
despite google and the O’Riley book I cant get my head around.

Can someone please give a simple explantion of what exactly an  
Enumerator is, what it can act on and why you can pass ‘array.to\_enum’  
to a method that expect ‘array’? What sort of objects can be defined as  
‘enumerable’ and what makes them so? What is the difference between and  
Enumerator and an Iterator?

Thanks in advance.

Imran Nazir

Imran’s profile" border=“0”\>  
Friend, Boho, House Owner, Citizen, Engineer
