use strict; use warnings; sub doSomething { #taint much but its something my $x=<<__EOF__ In the merry month of may The fields are decked with flowers gay Fa la la la, fa la la la, fa la la la, fa la la la The woods and groves with birds do sing Redoubling echos as they sing Fa la la la, fa la la la, fa la la la, fa la la la (Youll, 1608, #19) __EOF__ } sub doSomethingElse { # this is even less my $x=1+2; } { package Thingy; sub makeACall { my ($self, $addend) = @_; $$self += $addend; } } #---------------------------------------- my $N=scalar(@ARGV)?$ARGV[0] : 1000; my @array = (0..$N); my $incremented=0; my $self = bless(\$incremented, 'Thingy'); foreach (@array){ doSomething $self->makeACall($_); doSomethingElse } my $calculated = ($N*($N+1))/2; #operations ordered to avoid oddNum/2 print "added via loop: <$incremented> added via formula: <$calculated>\n"; #--------------------------------------- # why it is a *bad* idea to remove elements from an array while looping $$self = 0; #reset incremented; print "starting calc: $incremented\n"; foreach (@array) { doSomething $self->makeACall($_); shift @array; # get rid element, we don't need it anymore do we? doSomethingElse } # run this with even a measely 6 elements ($N=6) and you will see that # $incremented just doesn't add up to what it should print "deleting elements after use ...\n"; print "added via loop: <$incremented> added via formula: <$calculated>\n"; # # So why did we get 12 instead of 21? # - we deleted the element at the front of the array # - that moves whatever is at $array[1] to $array[0] # - ***the foreach loop doesn't know that we did that*** # - Perl goes to the next element (i.e. 1) # - what happens? only every other element in the original array # is visited: 0 + 2 + 4 + 6 = 12. #