From perlsyn's section on foreach loops:
If any element of LIST is an lvalue, you can modify it by modifying VAR inside the loop. Conversely, if any element of LIST is NOT an lvalue, any attempt to modify that element will fail.
What that's saying is that given:
use 5.010;
use Data::Dumper;
my $foo = "world";
my $bar = "Hello planet";
my $iter = 0;
foreach my $x ((1, $foo, substr($bar,6)))
{
local $@ = undef;
printf "Iteration %d:\n", ++$iter;
eval { $x = "World" } or say $@;
}
print Dumper [$foo, $bar];
The first iteration will fail as it's essentially trying to assign 1 = "Hello"; the other iterations will succeed because $foo and substr($bar,6) are both lvalues, so can be assigned to.
In your case, $_ is an alias for the constant 1, not an lvalue, so can't be assigned to.