In principle, and in practically any language, you'd want to pass objects that refer to data structures in the caller, pointers or references. In Perl, that would be a reference -- and you are doing that.
But then in the sub you create local copies; the $one
, @list
, and %hash
in the sub are lexical variables
local to sub's scope, masking/shadowing the ones in the calling scope. Changes to those don't do anything outside of sub's scope.
Instead, directly use the references that you passed in order to write to the caller's data.
sub foo {
my ($rscalar, $rary, $rhash) = @_;
$$rscalar = 2;
@$rary = (4,5,6);
$rhash->{'key'} = 'valueModified';
}
foo(\$one, \@list, \%hash);
Now $one
, @list
, and %hash
in the calling code have been changed. For details of working with references please see tutorial perlreftut and reference perlref.
Note that foo(\@allLocalArgs);
passes the reference of the array with arguments, so the sub receives one element -- that array's reference. You can do that but for the point of the question it isn't needed so I removed it and passed the list of arguments directly.
Another thing to note is that arguments are aliased in @_
-- so if in the sub you work with @_
directly then you may change data in the caller. So if you were to pass a scalar variable as foo($one)
then $_[0] = 2
in the sub changes $one
in the caller. This is in principle best avoided in my opinion; if caller's data is to be changed that should be made as explicit as possible; pass the reference.
A note on terminology
A list in Perl is an elusive, ephemeral structure used to move data around in a program; think of a bunch of scalars (values) on the stack somewhere, about to be used and disappear. Perhaps to pass arguments to a function (foo($v1, $v2)
), or to form a string (join '', $v1, $v2
), or to create an anonymous array reference ([$v1, $v2]
), etc.
The other use of the term is for a syntax property, of a grouping/collection of scalars (usually seen in parenthesis, but those are incidental and needed for precedence really).
An array, on the other hand, is a multi-valued variable. Much like a hash (associative array) is a multi-valued variable, and as opposed to a scalar, being a single-valued variable.
A lot has been written on this; here are a few links that came up readily: an Effective Perler article (with links to a few more articles), and a Stackoverflow page Perl array vs list.
In short, you are asking about a "scalar, array, hash."