Forum: Ruby What should I use instead of Generator in 1.9?

Posted by Andrew S. (andrew_s)
on 2012-08-12 21:46
Hi,

I have been using Generator in 1.8, and now I need to port that code to
1.9.  My code looks essentially like the code below.  I'm confused as to
what the correct option is in 1.9: Fibers? Enumerator?
Enumerator::generator?  I'd like to know the simplest most
straightforward option possible, since I'm still a relatively novice
Ruby practitioner.

Any help gratefully received!

require 'generator'

def bar
   Generator.new do |g|
      (1..10).each do |number|
         g.yield number
      end
   end
end

@foo = bar

while true
   if @foo.next?
      if (number = @foo.next)
         puts number.to_s
      end
   else
      exit
   end
end
Posted by Jan E. (jacques1)
on 2012-08-12 22:31
Hi,

An Enumerator is the right choice.

However, in your case you don't even need to explicitly create an 
Enumerator, because this will be done automatically when omitting the 
block for the "each" method:

@foo = (1..10).each

Most "each" methods work like that.
Posted by Andrew S. (andrew_s)
on 2012-08-13 00:25
Thanks!!  How do I implement the equivalent of generator's .next? method 
in order to avoid the following...

irb(main):001:0> @foo = (1..10).each
=> #<Enumerator: 1..10:each>
irb(main):002:0> while true
irb(main):003:1> puts @foo.next
irb(main):004:1> end
1
2
3
4
5
6
7
8
9
10
StopIteration: iteration reached an end
  from (irb):3:in `next'
  from (irb):3
  from /usr/local/bin/irb:12:in `<main>'
irb(main):005:0>
Posted by Sean O'halpin (sean)
on 2012-08-13 01:43
(Received via mailing list)
On Sun, Aug 12, 2012 at 11:25 PM, Andrew S. <lists@ruby-forum.com> 
wrote:
> Thanks!!  How do I implement the equivalent of generator's .next? method
> in order to avoid the following...
>
> irb(main):001:0> @foo = (1..10).each
> => #<Enumerator: 1..10:each>
> irb(main):002:0> while true
> irb(main):003:1> puts @foo.next
> irb(main):004:1> end
[snip]
> StopIteration: iteration reached an end

Well, you could just do this:

begin
  while true
    puts @foo.next
  end
rescue StopIteration
end

or even better (because loop catches the StopIteration for you):

loop do
  puts @foo.next
end

Regards,
Sean
Posted by Andrew S. (andrew_s)
on 2012-08-13 02:47
Thanks to all!
Posted by Jan E. (jacques1)
on 2012-08-13 07:29
Hi,

Why do you you even want an external iterator? Because what you've wrote 
down is an *internal* iterator created from an external iterator created 
from an internal iterator (which is a lot of useless code).
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.