Ruby Enumerator - why end with an exception?

Ruby's block iteration is fairly straightforward - it ends cleanly and moves on to the rest of the code.

Iterating with Enumerator, on the other hand, is a bit confusing. If you call: each without a block, an Enumerator is returned instead .: next then you can call it in Enumerator to get each next iterative value.

And then the odd part - when the iteration is completed, instead of a numbering that returns zero, it throws an exception: "The iteration is reached at the end." As a result, it does not even return a value.

For example:

test = [ 'test_value' ] enumerator = test.each enumerator.next >> "test_value" enumerator.next >> StopIteration: iteration reached at end 

Is the reason for this just so that nil values ​​can be returned by Enumerator? The answer comes to me only as I publish it (so I'm going to publish it yet), but it seems like it should be.

If so, is this a typical way to solve such problems? It seems strange to use an exception to handle code that essentially executes as expected.

+6
ruby exception enumerator
source share
2 answers

You are correct that the reason is that nil can be returned as a valid Enumerator value. To answer your question about whether this is typical, Python handles it in the same way, using an exception, also called StopIteration .

 >>> my_list = [1,2,3] >>> i = iter(my_list) >>> i.next() 1 >>> i.next() 2 >>> i.next() 3 >>> i.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration 

Of course, most of the time next not called directly ( each or the for loop is used instead), so this basic mechanism is often not displayed.

+6
source share

Yes, zero is still a result that is different from what it does not matter for the return. This is basically the same as trying to access a variable or location in memory that does not exist. This is why you want an exception instead of returning zero. Looks like you got it :-)

+3
source share

All Articles