I have heard that people shouldn't be using &
to call Perl subs, i.e:
function($a,$b,...);
# opposed to
&function($a,$b,...);
I know for one the argument list becomes optional, but what are some cases where it is appropriate to use the &
and the cases where you should absolutely not be using it?
Also how does the performace increase come into play here when omitting the &
?
Best Answer
I'm a frequent abuser of
&
, but mostly because I'm doing weird interface stuff. If you don't need one of these situations, don't use the&
. Most of these are just to access a subroutine definition, not call a subroutine. It's all in perlsub.Taking a reference to a named subroutine. This is probably the only common situation for most Perlers:
Similarly, assigning to a typeglob, which allows you to call the subroutine with a different name:
Checking that a subroutine is defined, as you might in test suites:
Removing a subroutine definition, which shouldn't be common:
Providing a dispatcher subroutine whose only job is to choose the right subroutine to call. This is the only situation I use
&
to call a subroutine, and when I expect to call the dispatcher many, many times and need to squeeze a little performance out of the operation:To jump into another subroutine using the current argument stack (and replacing the current subroutine in the call stack), an unrare operation in dispatching, especially in
AUTOLOAD
:Call a subroutine that you've named after a Perl built-in. The
&
always gives you the user-defined one. That's why we teach it in Learning Perl. You don't really want to do that normally, but it's one of the features of&
.There are some places where you could use them, but there are better ways:
To call a subroutine with the same name as a Perl built-in. Just don't have subroutines with the same name as a Perl built-in. Check perlfunc to see the list of built-in names you shouldn't use.
To disable prototypes. If you don't know what that means or why you'd want it, don't use the
&
. Some black magic code might need it, but in those cases you probably know what you are doing.To dereference and execute a subroutine reference. Just use the
->
notation.