I think I have misunderstood some aspects of argument passing to functions in Perl. What's the difference between func(\@array)
and func(@array)
?
AFAIK, in both functions, arguments are passed by reference and in both functions we can change the elements of @array
in the main program. So what's the difference? When should we use which?
@array = (1,2,3);
func(@array);
func(\@array);
sub func {
...
}
Also, how do I imitate pass-by-value in Perl? Is using @_
the only way?
func(\@array)
passes a reference.func(@array)
passes a list (of the elements in@array
). As Keith pointed out, these elements are passed by reference. However, you can make a copy inside the sub in order to pass by value.What you are after is this:
This will pass a copy of the arguments of
func
to@array
, which is a local variable within the scope of the subroutine.Documentation here
"change the elements of", yes. However, in the
func(@array)
case, the sub has no means to make other changes to the array (truncating it, pushing, popping, slicing, passing a reference to something else, even undef'ing it).I would avoid using the term "passed by reference", since the mechanism is completely different than Perl's references. It is less overloaded :) to say that in the sub,
@_
's elements start off aliased to the elements passed to the sub.It's impossible to pass arrays to subs. Subs take a list of scalars for argument. (And that's the only thing they can return too.)
You can pass a reference to an array:
You can pass the elements of an array:
If you want to pass more than just the elements of the array (e.g. pass
$x
,$y
and@a
), it can become tricky unless you pass a reference.If you're going to process lists (e.g.
sum mysub grep { ... } ...
), you might not want to pass a reference.If you want to modify the array (as opposed to just modifying the existing elements of the array), you need to pass a reference.
It can be more efficient to pass a reference for long arrays, since creating and putting one reference on the stack is faster than creating an alias for each element of a large array. This will rarely be an issue, though.
It's usually decided by one of the first two of the above. Beyond that, it's mostly a question of personal preference.