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


in reply to Changing an array from a sub

Since you already seem to know how references work, you can use them to get a clearer picture of what is happening.

use strict; use warnings; use feature 'say'; my @array = (1,2); say '@array is: ', \@array; say ' - ', \$array[0]; say ' - ', \$array[1]; say "Iterating over the elements:"; say ' - ', \$_ for @array; MyFunction(@array); sub MyFunction { say "In MyFunction"; say '@_ is: ', \@_; say ' - ', \$_[0]; say ' - ', \$_[1]; say "Slice"; @_[0,1] = (3,4); say ' - ', \$_[0]; say ' - ', \$_[1]; say "Array overwrite"; @_ = (5,6); say ' - ', \$_[0]; say ' - ', \$_[1]; }
@array is: ARRAY(0x6f66a0) - SCALAR(0x81ee20) - SCALAR(0x81ee38) Iterating over the elements: - SCALAR(0x81ee20) - SCALAR(0x81ee38) In MyFunction @_ is: ARRAY(0x724630) - SCALAR(0x81ee20) - SCALAR(0x81ee38) Slice - SCALAR(0x81ee20) - SCALAR(0x81ee38) Array overwrite - SCALAR(0x81f3c0) - SCALAR(0x81f3f0)
You can see that also @_ and @array are different (stored in separate locations), they contain exactly the same elements (you can imagine @_ as containing links to the elements of @A (actually called alias), and overwriting @_ overwrites those links (Although the @_[...] syntax accesses several, possibly all elements of an array, it's still an access to the contained elements, not the array itself). You can also see that $_ is an alias to the elements of the list.

Actually why the elements are aliased and not the array comes from the fact that lists are "flattened", meaning that containers are actually replaced by their contained elements. Eg in:

@a = (1,2); @b = (3,4); (@a,@b); # my list
The list is actually ($a[0], $a[1], $b[0], $b[1]) and the fact that those elements were in two different arrays isn't translated.