Is there a graceful way of realizing one is at the end of an enumerator?
For instance,
a = (1..10).to_a
e = a.each
e.next # should yield 1
while e.next
# do something
end
Of course, e raises StopIteration when you get to the end of the enumerator.
Is there a nice way of breaking out of that while loop without a rescue? I know that I can just say e.each (or just not use the enumerator at all), but for my specific problem I want to do something special for the first few iterations and then something general for the last few.
I want a way of looking at the next value and getting nil
instead of an error.
Any tips? There's probably something obvious that I'm missing...
NB. I don't have to use enumerators, but it seems like the easiest way to solve my problem. So if you have a non enumerator solution (for iterating through an enumerable), feel free to share. (on that note, maybe I should just use each or each_with_index and use the counter for the special cases...)
Rescuing from StopIteration
is the way to do it. And the only way.*
When you realize that any value (eg nil
, as you suggest) returned by next
could be the next value of the enumerable, it becomes clear that it's not possible for it to return a special-case value, since that could then never be in the enumerable. This is why next
must raise StopIteration
when complete instead of doing something more "graceful".
* Assuming you must use Enumerator
, as there's probably a better way to solve your real problem without doing so.
What's wrong with using each_with_index
like you suggest to have special behavior for the first N? This pattern shows up all the time:
a.each_with_index do |e, i|
if (i <= n)
# Do special stuff
end
# Do regular stuff
end
There's a lot of tools in the Enumerable toolbox you can make use of.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.