I think that one of the things that's mildly confusing in this area is that perl does an implicit "local" for you
whenever it sets $_ for you (in foreach, map and grep loops), but if you do the setting of $_ yourself, then you've got a new problem you don't see otherwise.
(I still don't understand why our "standard practice" doesn't include doing a "local $_" at the beginning of every sub... but then on the other hand, I guess it isn't all that common to get burned by $_ problems.)
Anyway, here's a script that demos what I'm talking about:
use warnings;
use strict;
use Test::More qw(no_plan);
# we're going to try doing various things to $_,
# and we want to see if it changes the initial value
my $initial_value = 'Some Value';
my @initial_array = qw( wun tew thuree foah fahv sex sevhun );
{#1 map perlfunc: "locally setting $_ to each element"?
my $testcase = "map";
my @array = @initial_array;
$_ = $initial_value;
my @whateva = map{ s/^f/F/ } @array;
is( $_, $initial_value, $testcase);
}
{#2 foreach
my $testcase = "foreach";
my @array = @initial_array;
$_ = $initial_value;
my @whateva = ();
foreach (@array) { s/^f/F/; push @whateva, $_ };
is( $_, $initial_value, $testcase);
}
{#3 while - this one fails
my $testcase = "while";
my @array = @initial_array;
$_ = $initial_value;
my @whateva = ();
while (@array) { $_ = pop @array; s/^f/F/; push @whateva, $_};
is( $_, $initial_value, $testcase);
}
{#4 while with local
my $testcase = "while with explicit local";
my @array = @initial_array;
$_ = $initial_value;
my @whateva = ();
while (@array) { local $_ = pop @array; s/^f/F/; push @whateva, $_};
is( $_, $initial_value, $testcase);
}
{#5 grep
my $testcase = "grep";
my @array = @initial_array;
$_ = $initial_value;
my @whateva = grep{ m/^f/ } @array;
is( $_, $initial_value, $testcase);
}