Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cycle through the rest of Enumerator in Ruby

I have an Enumerator in the middle of some sequence:

enum = (1..9).each
first = enum.next
second = enum.next

Now I want to cycle through the rest of the sequence (3..9 numbers). But seeming obvious solution (which works in python, e.g.), restart from the beginning of the sequence instead of the third item:

for item in enum
    puts item
end
# prints 1..9 instead of 3..9

Working solution which I found seems ugly:

begin
    while item=enum.next
        puts item
    end
rescue StopIteration
end

So the question: is there a nicer rubyish solution to do this thing? And why does for loop in Ruby act this way?

like image 820
vvch Avatar asked Apr 28 '18 09:04

vvch


People also ask

What is enumerator Ruby?

Enumerator, specifically, is a class in Ruby that allows both types of iterations – external and internal. Internal iteration refers to the form of iteration which is controlled by the class in question, while external iteration means that the environment or the client controls the way iteration is performed.

What does .each do in Ruby?

The each() is an inbuilt method in Ruby iterates over every element in the range. Parameters: The function accepts a block which specifies the way in which the elements are iterated. Return Value: It returns every elements in the range.


1 Answers

To answer your question directly, your current code is on the right lines but over-engineered. You only need to do:

enum = (1..9).each
first = enum.next
second = enum.next

loop { puts enum.next }

The loop will break as soon as the enum reaches its end; the loop automatically rescues StopIteration for you. It will only be re-raised if you call enum.next again, after the loop, which doesn't happen here.

However as pointed out by @mudasobwa, using enums like this quite ususual; more common would be to use (1..9).each_with_index and explicitly handle the first yields by their index.

like image 187
Tom Lord Avatar answered Sep 28 '22 06:09

Tom Lord