Idiom for array index that I'm foreach'ing over?

B

Brad Baxter

The code below ............

use strict;
use warnings;
use Array::Each qw/them rewind/;
$|=1;
while (1) {
my @array = map{rand}(1..10);
while (my ($k,$v) = them(@array)) {
print "[$k:$v]";
last if ($k == 0);
}
print "\nnext -> ";
### rewind(@array); # would fix it
}

produces..............

next -> [1:0][2:8]
next -> [0:4]
next -> [1:4][2:0]
next -> [0:1]
next -> [1:0][2:3]
next -> [0:0]
next -> [1:9][2:9]
next -> [0:1]
next -> [1:6][2:4]
next -> [0:1]
next -> [1:0][2:7]
next -> [0:0]

Hmmm, that's not what it produces for me, but I think I catch your drift.

I realize that this occurs, because the variable has the same
reference
even though it has completely changed. You might want to note
something
about breaking out of iteration and how you should call rewind if you
are
going to be using the same variable in a loop.

Good point. I think the OO interface would make this moot (meaning that
the scope of the blessed reference should determine the life of the
iterator), but there may be similar situations that the documentation
might make hints about.

Anyway, I could see how someone might write code that leaves entries
in your %set variable which are never deleted. This might be a
problem for a daemon.

Yes. I think the OO interface should take care of this, too.

Perhaps, some type of syntax as shown below would work.....
Without keeping a global hash.......
Of course it would have to be modified to iterate over multiple
arrays.

(I like your syntax better, I just don't like the way context is
maintained.
Although I don't see any better way to do it, while keeping your
syntax.)

I'm fond of "my syntax" :), too, but I think OO will win the day.

I really don't like the idea of the function being named each, but
that is just my opinion.

Since OO won't export it, I'm still leaning toward 'each'.

Thanks a bunch for the feedback,

Brad
 
B

Brad Baxter

By all means, go for an OO approach. This stuff has been shouting
"object" from the moment we introduced the %i hash with its keys to
distinguish different iterators.

The user will have to create an iterator object (instead of "spontaneously"
saying "( $i, $x, $y) = each( @x, @y)"), but it will be much clearer
what's happening.

I agree.

That's one of the advantages of explicit iterators.


Make each() return the index last (after the array elements) instead
of first. That way the first n values correspond to the n arrays, and
the index is easy to ignore when it isn't needed.

At first, I didn't like the sound of this, because I had been seeing this
correspondence between array and hash:

my( $index, $value ) = each( @a ) vs. my( $key, $value ) = each( %h )

But then I saw that the more meaningful correspondence might be the case
where someone is deliberately using parallel arrays instead of a hash:

my( $name, $value ) = each( @names, @values )

and may not care about the index. So now I agree with this suggestion.

Thanks!

Brad
 
B

Brad Baxter

(e-mail address removed)-berlin.de (Anno Siegel) wrote in message news:<[email protected]>...
Isn't there some type of Iterator package for perl? Why stop at arrays?
If there would be an OO approach, why not have iterators for many things.

Not that I found. While I agree you can have iterators for many things,
I'm pretty sure this isn't what I personally want to tackle. :) Your
examples gave me a good idea what you have in mind, but again, I'll plan
for now to stick with the parallel arrays case.

But it does make me wonder if Iterator::Array might be a better name for
the package. However, my own sense is to stay with Array::Each.

Partly this is because a high-level Iterator category makes me think it
ought to supply an abstract framework that would be extended for each kind
of iteration. I don't think this is the usual case for CPAN, it's just
what comes to mind. But that also is not something I would feel
comfortable taking on.

Many thanks,

Brad
 
B

Brad Baxter

I think an OO interface is a good idea. If you do that, don't return
the iteration value with the array values. Use a separate method for
that.

Perhaps something like this:

$set = Array::Each->new (@x, @y);
while (my ($x, $y) = $set->each())
{
print "Iteration number ", $set->index(), "\n";
print " x = $x; y = $y\n";
print " last iteration!\n" if $set->exhausted();
}
$set->rewind();

This sounds good to me, except that I do like Anno's suggestion to return
the iteration value as the last element. Your code above would work the
same--you would just be ignoring that element. I would still have a
method like index(), and I like the addition of exhausted().

Thanks!

Brad
 
B

Brad Baxter

I'm considering making a new module with the tentative name Array::Each.

A draft is available here:

http://www.vitabrevis.ws/perl/modules/Array/Each.pm
http://www.vitabrevis.ws/perl/modules/Array/Each.pod.html

So far, I've heard from Bryan, Anno, and Eric--many thanks. Not having
heard strong objections to Array::Each, I'm still leaning in that
direction. I'll also recode the module as an OO one, and present the
result for review before uploading to CPAN (assuming it doesn't crash and
burn). I can't say how soon this will be, given the scarcity of tuits
right about now, but I don't expect anyone will necessarily miss it in the
mean time.

Best regards,

Brad
 
D

Darren Dunham

Eric J. Roode said:
Alas, very slim. :-( I have this nagging feeling that version 6 is
going to be the worst thing that ever happened to Perl.

New Coke?
 

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

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top