When should I use the & to call a Perl subroutine?

user105033 picture user105033 · Aug 28, 2009 · Viewed 34k times · Source

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 &?

Answer

brian d foy picture brian d foy · Aug 28, 2009

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.

  1. Taking a reference to a named subroutine. This is probably the only common situation for most Perlers:

     my $sub = \&foo;
    
  2. Similarly, assigning to a typeglob, which allows you to call the subroutine with a different name:

     *bar = \&foo;
    
  3. Checking that a subroutine is defined, as you might in test suites:

     if( defined &foo ) { ... }
    
  4. Removing a subroutine definition, which shouldn't be common:

     undef &foo;
    
  5. 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:

     sub figure_it_out_for_me {
        # all of these re-use the current @_
          if( ...some condition... ) { &foo     } 
       elsif( ...some other...     ) { &bar     }
       else                          { &default }
       }
    
  6. 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:

     goto ⊂
    
  7. 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:

  1. 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.

  2. 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.

  3. To dereference and execute a subroutine reference. Just use the -> notation.