in reply to Re: Small troubles with references
in thread Small troubles with references

The difference is that passing an array to a subroutine passes a copy of that array

Not true at all. @_ is aliased to all of the elements of the list passed to the subroutine. There is no copying going on unless you, the programmer, do it.

Replies are listed 'Best First'.
Re^3: Small troubles with references
by demerphq (Chancellor) on Feb 09, 2006 at 20:33 UTC

    A lot of newbies are unfamiliar with the distinction between an alias and a reference. And I think we should keep it that way. The fact that an alias is a reference that need not be dereferenced for use is pretty deep and dark voodoo that might confuse a beginner.

    :-)

    ---
    $world=~s/war/peace/g

      I'll bite. I'm not a Perl newbie, but there are certainly holes in my largely self-taught knowledge of Perl. I would guess that the reason the change to the array isn't permanent when it is passed by value is because of lexical scoping ... but the idea of the passed parameter being an alias under the covers is confusing to me. Would anyone care to explain?


      No good deed goes unpunished. -- (attributed to) Oscar Wilde

        Consider

        sub foo { my $x=shift; $x="Changed1"; $_[0]="Changed2"; } my $i="Orig1"; my $j="Orig2"; print "$i,$j\n"; foo($i,$j); print "$i,$j\n"; __END__ Orig1,Orig2 Orig1,Changed2

        Assigning to $_[$x] is the same as assigning to the original value that was passed into the subroutine. This is because its an alias. Its not a copy. IOW, its where two or more variable names refer to the same memory location. Its much as if you did

        sub bar { my $ref=shift; $$ref='changed' } bar(\$j);

        Except you dont have to deref before you do the assignment.

        for() aliases, as does map, and a few other places where it can be useful to have this behaviour.

        ---
        $world=~s/war/peace/g

        @_ is an array of aliases to the argument list. Try:
        sub inc_list { $_++ for @_; } my @arr = (1, 2); inc_list(@arr); print "@arr\n"; # prints "2 3" (untested)