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