How are Ruby iterators implemented?

R

Roshan James

------_=_NextPart_001_01C5498D.C7C27962
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

How are iterators implemented in Ruby?=20
=20
Sometime back I had asked a questuin about invoking iterators in
locksteps and I was told that iterators in ruby are implemented as
closures that are passed to the called method. If iterators are passed
as closures then,
1) Every consumer of the iterator should undergo closure conversion
in some way
2) How is "break" implemented ?
This similar to how it would be done in Scheme or similar language that
inherently supports closures.=20
=20
=20
I was reading about CLU (the parent language for the iterator concept),
and they implemnted iterators on a single stack. I believe that that
would involve have caller and callee function frames to live on the
stack at the same time. The iteration would be implemnetd as goto
between these functions with a corresposding shift in stock location to
refernce locals. This implementation has the inherent limitation of not
being able to do multiple itetarors in lock step.=20
=20
Another alternative is that the itetror is converted to an object that
maintains state - a classical generator. This is what C# and Py do.=20
=20
How does Ruby do iterators ?
=20
Roshan

------_=_NextPart_001_01C5498D.C7C27962--
 
A

Austin Ziegler

How are iterators implemented in Ruby?

Sometime back I had asked a questuin about invoking iterators in
locksteps and I was told that iterators in ruby are implemented as
closures that are passed to the called method. If iterators are
passed as closures then, 1) Every consumer of the iterator should
undergo closure conversion in some way 2) How is "break"
implemented ? This similar to how it would be done in Scheme or
similar language that inherently supports closures.

I was reading about CLU (the parent language for the iterator
concept), and they implemnted iterators on a single stack. I
believe that that would involve have caller and callee function
frames to live on the stack at the same time. The iteration would
be implemnetd as goto between these functions with a corresposding
shift in stock location to refernce locals. This implementation
has the inherent limitation of not being able to do multiple
itetarors in lock step.

Another alternative is that the itetror is converted to an object
that maintains state - a classical generator. This is what C# and
Py do.

How does Ruby do iterators ?

What I'm getting ready to tell you is as far as I understand it; it
may not be completely correct -- and the most authoritative way to
see this is the source.

That said, simple iterators like #each implement a loop through the
container and yield the object in the iterator to the provided code
block. #each suspends execution until the block (closure) finishes
executing. That would generally indicate a change in stack frame.

Ruby does have generators available, but they're overkill for ~95%
of cases.

-austin
 
R

Robert Klemme

The iterator is not the closure. The closure (aka block) is just for
executing some piece of code on each element it's given. The iteration
itself is typically implemented in #each (or any other method). Most of
the time (i.e. if you do not use Generator) you cannot access an iterator.
You just have a method that accepts a block.

You can easily implement an iteration yourself, like

class Demo
def initialize(st,en) @start, @end = st, en end

def each
i = @start

while i <= @end
yield i
i += 1
end

self
end
end
1
2
3
4
5
=> # said:
If iterators are

I'm not sure what you're getting at here. Since there is no iterator I'd
say that in itself is reason enough that there is no closure conversion.
:) Other than that, I don't see why a closure should be converted.
Maybe I'm lacking understanding of other languages.

Does this illustrate the behavior?
1
2
3
4
=> "end"

"break" simply terminates the iterating method (#each in this case) and
forces return of the provided value (if there is any, nil is the default).

No, we actually have a method call here. That's quite obvious if you
choose the other alternative for the implementation:

class Demo
def each2(&b)
i = @start

while i <= @end
b.call( i )
i += 1
end

self
end
end
1
2
3
4
5


What I'm getting ready to tell you is as far as I understand it; it
may not be completely correct -- and the most authoritative way to
see this is the source.

That said, simple iterators like #each implement a loop through the
container and yield the object in the iterator to the provided code
block. #each suspends execution until the block (closure) finishes
executing. That would generally indicate a change in stack frame.

Yes, you can view a block as an anonymous callback function.
Ruby does have generators available, but they're overkill for ~95%
of cases.

Perfectly agree.

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top