Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

use Data::Dumper; my @arr=(1,2,3,4,5,6,7,8,9,10); my $var; foreach(@arr){ print "foreach takes :"."$_\n"; $var=shift @arr; print "shift removes :"."$var\n"; } print Dumper \@arr;

In the above code I used foreach loop to remove the elements from the array "@arr" by using the shift operator, Initially the foreach loop will take list of values, but when the array gets modified the foreach also getting affected why? Is it wrong using shift with foreach ?

Replies are listed 'Best First'.
Re: foreach problem with shift
by lakshmananindia (Chaplain) on Mar 04, 2009 at 10:39 UTC
    From Dominus blog

    On the first iteration, the loop processes the first element in the array. On the second iteration, the loop processes the second element in the array, whatever that element is at the time the second iteration starts, whether or not that was the second element before. On the third iteration, the loop processes the third element in the array, whatever it is at that moment. And so the loop continues, terminating the first time it is called upon to process an element that is past the end of the array.

    If you don't want that behavior, then use the foreach as follows

    foreach ((), @arr)

    I also suggest you to have a look at How foreach decides

Re: foreach problem with shift
by johngg (Canon) on Mar 04, 2009 at 12:10 UTC

    Nothing to do with your problem with Foreach Loops but I'm wondering why you are concatenating two strings in your print statement when one would do. This

    print "foreach takes :"."$_\n";

    could be written

    print "foreach takes :$_\n";

    Cheers,

    JohnGG

Re: foreach problem with shift
by vinoth.ree (Monsignor) on Mar 04, 2009 at 10:35 UTC

    I'm sorry, The above question is asked by me only

    .

      Read perlsyn about foreach:

      If any part of LIST is an array, foreach will get very confused if you add or remove elements within the loop body, for example with splice. So don't do that.