Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl using the special character &

Tags:

perl

I had a small question. I was reading some code and as my school didn't teach me anything useful about perl programming, I am here to ask you people. I see this line being used a lot in some perl programs:

$variable = &something();

I don't know what the & sign means here as I never say it in perl. And the something is a subroutine ( I am guessing). It usually says a name and it has arguments like a function too sometimes. Can someone tell me what & stands for here and what that something is all the time.

The variable takes in some sort of returned value and is then used to check some conditions, which makes me think it is a subroutine. But still why the &?

Thanks

like image 606
ban Avatar asked Jun 18 '13 16:06

ban


2 Answers

Virtually every time you see & outside of \&foo and EXRP && EXPR, it's an error.


  • &foo(...) is the same as foo(...) except foo's prototype will be ignored.

    sub foo(&@) { ... }      # Cause foo to takes a BLOCK as its first arg
    
    foo { ... } ...;
    &foo(sub { ... }, ...);  # Same thing.
    

    Only subroutines (not operators) will be called by &foo(...).

    sub print { ... }
    print(...);         # Calls the print builtin
    &print(...);        # Calls the print sub.
    

    You'll probably never need to use this feature in your entire programming career. If you see it used, it's surely someone using & when they shouldn't.

  • &foo is similar to &foo(@_). The difference is that changes to @_ in foo affects the current sub's @_.

    You'll probably never need to use this feature in your entire programming career. If you see it used, it's surely someone using & when they shouldn't or a foolish attempt at optimization. However, the following is pretty elegant:

    sub log_info  { unshift @_, 'info';  &log }
    sub log_warn  { unshift @_, 'warn';  &log }
    sub log_error { unshift @_, 'error'; &log }
    
  • goto &foo is similar to &foo, except the current subroutine is removed from the call stack first. This will cause it to not show up in stack traces, for example.

    You'll probably never need to use this feature in your entire programming career. If you see it used, it's surely a foolish attempt at optimization.

    sub log_info  { unshift @_, 'info';  goto &log; } # These are slower than
    sub log_warn  { unshift @_, 'warn';  goto &log; } # not using goto, but maybe
    sub log_error { unshift @_, 'error'; goto &log; } # maybe log uses caller()?
    
  • $& contains what the last regex expression match matched. Before 5.20, using this causes every regex in your entire interpreter to become slower (if they have no captures), so don't use this.

    print $&        if /fo+/;     # Bad before 5.20
    print $MATCH    if /fo+/;     # Bad (Same thing. Requires "use English;")
    print ${^MATCH} if /fo+/p;    # Ok (Requires Perl 5.10)
    print $1        if /(fo+)/;   # Ok
    
  • defined &foo is a perfectly legitimate way of checking if a subroutine exists, but it's not something you'll likely ever need. There's also exists &foo is similar, but not as useful.

  • EXPR & EXPR is the bitwise AND operator. This is used when dealing with low-level systems that store multiple pieces of information in a single word.

    system($cmd);
    die "Can't execute command: $!\n"       if $? == -1;
    die "Child kill by ".($? & 0x7F)."\n"   if $? & 0x7F;
    die "Child exited with ".($? >> 8)."\n" if $? >> 8;
    
  • &{ EXPR }() (and &$ref()) is a subroutine call via a reference. This is a perfectly acceptable and somewhat common thing to do, though I prefer the $ref->() syntax. Example in next item.

  • \&foo takes a reference to subroutine foo. This is a perfectly acceptable and somewhat common thing to do.

    my %dispatch = (
       foo => \&foo,
       bar => \&bar,
    );
    
    my $handler = $dispatch{$cmd} or die;
    $handler->();
    # Same:  &{ $handler }();
    # Same:  &$handler();
    
  • EXPR && EXPR is the boolean AND operator. I'm sure you're familiar with this extremely common operator.

    if (0 <= $x && $x <= 100) { ... }
    
like image 98
ikegami Avatar answered Oct 04 '22 01:10

ikegami


In older versions of perl & was used to call subroutines. Now this is not necessary and \& is mostly used to take a reference to subroutine,

my $sub_ref = \&subroutine;

or to ignore function prototype (http://perldoc.perl.org/perlsub.html#Prototypes)

Other than for referencing subroutines & is bitwise and operator,

http://perldoc.perl.org/perlop.html#Bitwise-And

like image 29
mpapec Avatar answered Oct 03 '22 23:10

mpapec