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
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) { ... }
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