In loops like this, Perl does some magic that other popular programming languages generally do not. For folks who come from other languages or are not familiar with this magic, it can be surprising, and often in negative ways.

You might normally think that the value of each element in the list is copied to the loop variable ($item in this case). In fact, the loop variable becomes a synonym for the elements of the list. This means that if you modify the loop variable, it will modify the object inside the list to which it is currently referencing.

To be even more specific, this only applies when the list element currently being processed is an "lvalue" (fancy language for "something that can be modified"). So, if the code is

foreach my $item ($a, 2, $c) { $item = 1; }
then $a and $c will be set to 1, but the constant "2" will be copied into $item, $item will be changed to 1 and the constant "2" will be left alone.

This is why your first code sample works the way that you want it to. You have listed the actual variables you want to modify inside the foreach loop.

In your second sample, you are first copying the values in your variables into a new array and using that array in the loop. Now, you're modifying the elements of the array inside the loop and not the original variables.

Another place where this type of synonym behavior works is in calls to subroutines. The elements of @_ are actually referencing the variables of the caller's parameters (where they are lvalues). Most of the time we tend to copy @_ elements into local variables; modifying those will not modify the caller's data.

But I ramble.

-- Eric Hammond


In reply to Re: array confusion by esh
in thread array confusion by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.