This is about context in Perl. It is a crucial aspect of the language.
An expression like
my $var = @ary;
attempts to assign an array to a scalar.
That doesn't make sense as it stands and what happens is that the right-hand side is evaluated to the number of elements of the array and that is assigned to $var
.
In order to change that behavior you need to provide the "list context" to the assignment operator.† In this case you'd do
my ($var) = @ary;
and now we have an assignment of a list (of array elements) to a list (of variables, here only $var
), where they are assigned one for one. So here the first element of @ary
is assigned to $var
. Please note that this statement plays loose with the elusive notion of the "list."
So in your case you want
my ($ref) = @_;
and the first element from @_
is assigned to $ref
, as needed.
Alternatively, you can remove and return the first element of @_
using shift, in which case the scalar-context assignment is fine
my $ref = shift @_;
In this case you can also do
my $ref = shift;
since shift
by default works on @_
.
This is useful when you want to remove the first element of input as it's being assigned so that the remaining @_
is well suited for further processing. It is often done in object-oriented code.
It is well worth pointing out that many operators and builtin facilities in Perl act differently depending on what context they are invoked in.
For some specifics, just a few examples: the regex match operator returns true/false (1/empty string) in scalar context but the actual matches in list context,‡ readdir returns a single entry in scalar context but all of them in list context, while localtime shows a bit more distinct difference. This context-sensitive behavior is in every corner of Perl.
User level subroutines can be made to behave that way via wantarray.
†
See Scalar vs List Assignment Operator
for a detailed discussion
‡
See it in perlretut and in perlop for instance