Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I came across this and I'm not sure why it happens, can anyone explain?
use strict; use warnings; my @outer = (qw| one two three |); print "First\n"; foreach my $o (@outer) { print $o, "\n"; } print "Second\n"; foreach my $o (@outer) { $o .= 'loop'; print $o, "\n"; } #print $o, "\n"; # Comment out compile time error print "Third\n"; foreach my $o (@outer) { print $o, "\n"; }
$o is being carried through to each foreach loop but is not available outside. I don't get it. Ideas?

Replies are listed 'Best First'.
Re: foreach my $var scope oddness
by ikegami (Patriarch) on May 21, 2006 at 00:40 UTC

    In a foreach loop, the loop variable ($o in this case, $_ if none is specified) is a alias to (not a copy of) the current element of the list over which the loop interates. Any changes to the loop variable is reflected back to the list element.

    In other words

    foreach my $o (@outer) { $o .= 'loop'; print $o, "\n"; }

    is the same as

    $outer[0] .= 'loop'; print $outer[0], "\n"; $outer[1] .= 'loop'; print $outer[1], "\n"; $outer[2] .= 'loop'; print $outer[2], "\n";

    Update: Switched to terminology that's more appropriate for Perl, as per Grandfather's recommendations.

      <nitpick>Actually "is an alias to", not "is a reference". The loop variable doesn't get dereferenced to access the current element - it is in essence the current element.</nitpick>

      I find it better to refer to it as the "loop variable" rather than the "index variable". In Perl it is seldom an index and even when it is, it is still the "loop variable" and is aliased to each list item in turn.


      DWIM is Perl's answer to Gödel
Re: foreach my $var scope oddness
by merlyn (Sage) on May 20, 2006 at 23:59 UTC
Re: foreach my $var scope oddness
by Zaxo (Archbishop) on May 21, 2006 at 00:12 UTC

    $o is scoped to each loop, but it is an alias to each element of @outer in turn.

    After Compline,
    Zaxo

Re: foreach my $var scope oddness
by jesuashok (Curate) on May 21, 2006 at 05:12 UTC
    Hi

    use strict; use warnings; my @outer = (qw| one two three |); print "First\n"; foreach my $o (@outer) { print $o, "\n"; } print "Second\n"; foreach my $o (@outer) { $o .= 'HIII'; print $o, "\n"; } print "ARRAY " , @outer , "\n"; #print $o, "\n"; # Comment out compile time error print "Third\n"; foreach my $o (@outer) { print $o, "\n"; }
    Output :-
    First one two three Second oneHIII twoHIII threeHIII ARRAY oneHIIItwoHIIIthreeHIII Third oneHIII twoHIII threeHIII
    This is just to make you clear on what had happened in the following loop:-
    foreach my $o (@outer) { $o .= 'HIII'; print $o, "\n"; }
    The above loop actually modifies the value in the Memory region where it is pointing to. $o points the memory region of all indexes of array. so It modifies the element of array.

    "Keep pouring your ideas"