in reply to Re^4: Array Processing
in thread Array Processing

But then, when I looked more carefully at the idiom you suggested, there's a subtle bug in: while ( (my $a, @a) = @a ) {". I realized it doesn't, in fact, reasign most of @a to iteslf every time, because you're declaring my @a (along with my $a), so it's a different @a that you're doing the assignment to! Also, when you run it, you get an infinite loop:
You are talking about the code I wrote, but the code you actually tested is very different. There is a big difference between
(my $a, @a) = @a
and
my ($a, @a) = @a
In the first case, only $a is redeclared with my. The @a variable is the same one on both sides. In the second case, both $a and @a are redeclared with my. Notice that in my reply, I used the first one. There is no infinite loop, and it really does work like I described.
So for now, I'll stick with the "while (defined($a = shift @a))" syntax.
Again, this will fail if there is an undef in the array. You can't get undef from <$fh> unless it's the end of the file, so it is safe to test the result of <$fh> for undef. But it is perfectly reasonable to have undef as a value in an array (and not be at the end of the array).

blokhead

Replies are listed 'Best First'.
Re^6: Array Processing
by liverpole (Monsignor) on Oct 08, 2005 at 20:10 UTC
    Whoa -- my sincere apologies!  I can only surmise that I read it too quickly and my fingers typed in the idiom that they were used to.  So I sheepishly retract what I said about your infinite loop:
    my @a = qw(1 2 3 4 5); while ((my $a, @a) = @a) { printf "\$a is now '%s', and \@a is now (%s)\n", $a, join(')(',@a) +; } # Output ... $a is now 1, and @a is now (2)(3)(4)(5) $a is now 2, and @a is now (3)(4)(5) $a is now 3, and @a is now (4)(5) $a is now 4, and @a is now (5) $a is now 5, and @a is now ()
    My initial reaction was that it's wasteful to reassign the entire array, but then I saw you had already noted this inefficiency.

    And yes, it's a reasonable observation about the possibility of an undef element, but in most cases one doesn't need to deal with arrays containing undefined values.  Then of course you'd be better off with something like:

    while (@a) { my $a = shift @a; # Use $a ... }
    Or what BUU suggests next ... :-)