in reply to Changing array by changing $_?

If you are looping over an array, the array element is aliased to the loop variable ($_ in your case). The loop variable is just another name for the array element, it isn't a copy.

This is a feature. It's designed this way.

If you don't want to modify the original element, make a copy first. For instance:

foreach (@array) { local $_ = $_; # Change 'local' to 'my' in 5.10. ... }

Replies are listed 'Best First'.
Re^2: Changing array by changing $_?
by johnvandam (Acolyte) on Oct 13, 2008 at 12:17 UTC

    Thank you! Now it makes perfect sense. I am actually in the habit of using

    foreach my $variable (@array) { doingStuffWith($variable); }

    I guess that also prevents the elements from being changed. Thanks again for showing me the perl 'magic'.

    20081016 Janitored by Corion: Closed code tag, as per Writeup Formatting Tips

      Nope.

      foreach my $foo (@bar) { $foo .= 'ack' ; ... } ;
      will affect the contents of the array just as surely as:
      foreach (@bar) { $_ .= 'ack' ; ... } ;
      To avoid this you need to:
      foreach (@bar) { my $s = $_ . 'ack' ; ... } ;
      or similar.

      It's genuine Perl magic. Useful once you know it. A chunk out of your backside when you don't.

      That doesn't help the fact that you are modifying a global variable ($_) without localizing it first. Why use a global variable at all!
      foreach (@species) { ( my $species = $_ ) =~ s/^-//; unless (exists $refspecies{$species}) { die "$species is not in the species table\n"; } }

      Are you aware that:

      use strict; use warnings; my @array = 1 .. 10; doingStuffWith ($_) for @array; print "@array"; sub doingStuffWith { $_[0] +=10; }

      Prints:

      11 12 13 14 15 16 17 18 19 20

      It's aliases all the way down.


      Perl reduces RSI - it saves typing
      No, it won't.

      Loop variables are always aliases for the elements of the array.
      So it doesn't matter whether you give them a name or not.