in reply to Unshift and push inside of map operation.

I'd probably use two arrays -- one to be processed, and one of what's already been processed:

my @toprocess = qw (a1 a2 a3 a4 a5); my @processed = (); my $i = 10; # avoid an infinite loop while (my $item = shift @toprocess) { push @toprocess, 'x' ; unshift @processed, 'y' ; push @processed, $item; print "array has ". scalar @toprocess. " items left. This one is +$item\n"; last unless $i--; # break out of infinite loop for this example }

Replies are listed 'Best First'.
Re^2: Unshift and push inside of map operation.
by ikegami (Patriarch) on Sep 23, 2008 at 04:43 UTC
    while (my $item = shift @toprocess)

    will fail if one of the items evaluates to false. You want to check "if an item has been returned", not "if an item has been returned and its true". Fix:

    while (my ($item) = shift @toprocess)

    A list assignment in scalar context returns the number of items being assigned.

    Update: Oops, I'm used to dealing with iterators that return () when out of data. As per tye's reply, my fix makes things worse. The following allows false values without introducing an infinite loop:

    while (@toprocess) { my $item = shift @toprocess;

    Due to the extra complexity, it might make more sense to the simpler original if it's safe.

      I suspect you haven't tested this. It might seem reasonable to assume that shift on an empty array returns an empty list. However, my testing on Perl 5.8.8 and 5.10 shows that shift @empty returns a single undef, not an empty list and your example produces an endless loop.

      - tye        

        However, my testing on Perl 5.8.8 and 5.10 shows that shift @empty returns a single undef, not an empty list
        This is actually the documented behaviour, not (just) a quirk of implementation: shift.