From: Hal Fulton on
[Note: parts of this message were removed to make it a legal post.]

Hi, all...

I'm trying to grasp when/why one might use a generator instead of
an enumerator (or vice versa).

I've used generators, but enumerators are newer to me.

I've heard one person's take on this (thanks David!) but thought
I might ask more thoughts...

Thanks,
Hal Fulton

From: Ricardo Panaggio on
Hello Hal

Generators "externalize" iteration, whereas Enumerator "internalize"
it (but this docs may have already told you).

Generators can be used to create a "controlled stream" of objects,
that you can operate as you where using a remove control: go to the
next (Generator#next), give me the position (Generator#pos), return to
the beginning (Generator#rewind), ...

Enumerator offers methods to iterate through the entire stream, like
iterate using a windows of size X (Enumerator#each_cons), iterate
using slices from the stream (Enumerator#each_slide), ...

They are quite different in use, although both are usable to iterate over data.

On Wed, Jul 21, 2010 at 22:12, Hal Fulton <rubyhacker(a)gmail.com> wrote:
> Hi, all...
>
> I'm trying to grasp when/why one might use a generator instead of
> an enumerator (or vice versa).
>
> I've used generators, but enumerators are newer to me.
>
> I've heard one person's take on this (thanks David!) but thought
> I might ask more thoughts...
>
> Thanks,
> Hal Fulton
>

From: Robert Klemme on
2010/7/22 Hal Fulton <rubyhacker(a)gmail.com>:
> I'm trying to grasp when/why one might use a generator instead of
> an enumerator (or vice versa).

It seems the alternative is Generator vs. Enumerable rather than
Generator vs. Enumerator. Enumerator is rather a special form of
Enumerable which allows to do some things more efficiently because it
delays the iteration. E.g.

# traditional one liner style: needs much memory:
matches = File.readlines("foo").select {|line| /keyword/ =~ line}

# Enumerator: only memory for the
matches = File.to_enum(:foreach, "foo").select {|line| /keyword/ =~ line}

# Same in 1.9 with implicit Enumerator creation
matches = File.foreach("foo").select {|line| /keyword/ =~ line}

It's a convenient replacement for the equally efficient (memory wise):

matches = []

File.foreach "foo" do |line|
matches << line if /keyword/ =~ line
end

Generator is a completely different iteration style as Ricardo explained.

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

From: David A. Black on
Hi --

On Thu, 22 Jul 2010, Ricardo Panaggio wrote:

> Hello Hal
>
> Generators "externalize" iteration, whereas Enumerator "internalize"
> it (but this docs may have already told you).
>
> Generators can be used to create a "controlled stream" of objects,
> that you can operate as you where using a remove control: go to the
> next (Generator#next), give me the position (Generator#pos), return to
> the beginning (Generator#rewind), ...

Enumerators have #next and #rewind too, though (though not #pos). In
1.9, as far as I can tell, the generator.rb library has been removed,
and Generator is now a class inside Enumerator. An Enumerator::Generator
is created automatically, for the use of the enumerator, if you create
an enumerator with a block. Also, these Generators don't have #next and
friends; that's available via the enumerator. (I'm not sure what
happened to #pos.)

As I understand it, the main thing about generators is that "controlled
stream" thing, where you can roll your own sense of iteration, rather
than just piggy-backing on what some enumerable object with its own
ideas about iteration thinks. Here's a (very contrived) 1.9 example:

[dblack(a)ruby-versions ~]$ cat e.rb
message = nil

g = Enumerator::Generator.new do |yielder|
yielder << "Hi."
puts "I've been told to #{message}."
case message
when "leave"
yielder << "Bye."
when "stay"
yielder << "I'm still here!"
end
end

e = Enumerator.new(g)

puts e.next
message = "stay"
puts e.next

e.rewind

puts e.next
message = "leave"
puts e.next

[dblack(a)ruby-versions ~]$ ruby e.rb
Hi.
I've been told to stay.
I'm still here!
Hi.
I've been told to leave.
Bye.


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com

From: Ricardo Panaggio on
On Thu, Jul 22, 2010 at 07:11, David A. Black <dblack(a)rubypal.com> wrote:
> Hi --
>
> On Thu, 22 Jul 2010, Ricardo Panaggio wrote:
>
>> Hello Hal
>>
>> Generators "externalize" iteration, whereas Enumerator "internalize"
>> it (but this docs may have already told you).
>>
>> Generators can be used to create a "controlled stream" of objects,
>> that you can operate as you where using a remove control: go to the
>> next (Generator#next), give me the position (Generator#pos), return to
>> the beginning (Generator#rewind), ...
>
> Enumerators have #next and #rewind too, though (though not #pos). In
> 1.9, as far as I can tell, the generator.rb library has been removed,

I wasn't aware of it in 1.9. Good to now :)

> and Generator is now a class inside Enumerator. An Enumerator::Generator
> is created automatically, for the use of the enumerator, if you create
> an enumerator with a block. Also, these Generators don't have #next and
> friends; that's available via the enumerator. (I'm not sure what
> happened to #pos.)
>
> As I understand it, the main thing about generators is that "controlled
> stream" thing, where you can roll your own sense of iteration, rather
> than just piggy-backing on what some enumerable object with its own
> ideas about iteration thinks. Here's a (very contrived) 1.9 example:
>
> [dblack(a)ruby-versions ~]$ cat e.rb message = nil
>
> g = Enumerator::Generator.new do |yielder|
>  yielder << "Hi."
>  puts "I've been told to #{message}."
>  case message
>  when "leave"
>    yielder << "Bye."
>  when "stay"
>    yielder << "I'm still here!"
>  end
> end
>
> e = Enumerator.new(g)
>
> puts e.next
> message = "stay"
> puts e.next
>
> e.rewind
>
> puts e.next
> message = "leave"
> puts e.next
>
> [dblack(a)ruby-versions ~]$ ruby e.rb Hi.
> I've been told to stay.
> I'm still here!
> Hi.
> I've been told to leave.
> Bye.
>
>
> David
>
> --
> David A. Black, Senior Developer, Cyrus Innovation Inc.
>
>  The                   Ruby training with Black/Brown/McAnally
>  Compleat              Philadelphia, PA, October 1-2, 2010
>  Rubyist               http://www.compleatrubyist.com
>
>

 |  Next  |  Last
Pages: 1 2
Prev: Writing to file delay
Next: finding last line in a file