http://www.perlmonks.org?node_id=72632


in reply to NEWBIE Brain Teaser

First of all: ++ nysus and kudra for promoting learning
Since nobody posted the reason why it does this I figured I'd do so. In fact, instead of waste my time, I just took this from "Learning Perl" written by Randal Schwartz, Published by OReilly Associates.

If the list you are iterating over is made of real variables rather than some function returning a list value, then the variable being used for iteration is in fact an alias for each variable in the list instead of being merely a copy of the values. It means that if you change the scalar variable, you are also changing that particular element in the list that the variable is standing in for. For example:

@a = (3,5,7,9);
foreach $one (@a) {
$one *= 3;
}
# @a is now (9,15,21,27)

Notice how altering $one in fact altered each element of @a. This is a feature, not a bug.


Macphisto the I.T. Ninja

Everyone has their demons....

Replies are listed 'Best First'.
About this behavior
by chumley (Sexton) on Apr 16, 2001 at 05:03 UTC

    Thanks for the explanation. I've learned something new about Perl - which isn't too difficult for me!

    I'm just wondering why it's set up this way? Is there an overall principle I can apply to lists, arrays, scalars, hashes, etc., that will help me understand behavior like this?

    Or perhaps I should go back and finish reading "Learning Perl" instead of picking up little bits here and there as I need them. :-\

    Chumley

      Well, and someone please correct me if I mislead on this post,

      If you think about the code:
      foreach $each (@list) {
      $each *= 2;
      $newlist$i = $each;
      ++$i;
      }


      From Programming Perl: Note that the loop variable becomes a reference to the element itself, rather than a copy of the element. Hence, modifying the loop variable will modify the original array.

      The snippet loops through the contents of @list and as each cell gets looked at, it is assigned to $each. $each is then modified by multiplying by 2. Modifying $each, modifies the value in the shell, due to the way foreach is constructed in perl. I believe that is all correct. If I have made any mistakes ( other than grammar, and spelling ), someone please tell me.

      Macphisto the I.T. Ninja

      Everyone has their demons....