Perl Cheatsheet
Control Flow and Subs
Use this Perl reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
if / elsif / else
if ($score >= 90) { print "A\n"; } elsif ($score >= 80) { print "B\n"; } else { print "practice\n"; } print "ok\n" if $ok; # statement modifier
Loops
for my $item (@items) { print "$item\n"; } for (my $i = 0; $i < @items; $i++) { print "$i: $items[$i]\n"; } while (my $line = <STDIN>) { chomp $line; next if $line eq ""; last if $line eq "quit"; }
Loop Control
next; # skip to next iteration last; # break out of loop redo; # restart current iteration without condition
Subroutines with Signatures
Signatures are stable since Perl 5.36 and enabled by use v5.36;.
use v5.36; sub greet ($name, $greeting = "Hello") { return "$greeting, $name"; } sub total (@nums) { # slurpy trailing array my $sum = 0; $sum += $_ for @nums; return $sum; } sub configure (%opts) { # slurpy trailing hash return $opts{port} // 3000; } say greet("Ada"); # Hello, Ada
Legacy code (and code that must run on old Perls) unpacks @_ by hand:
sub greet { my ($name) = @_; return "Hello, $name"; }
state and Lexical Scope
my $outer = 1; # lexical: visible to end of enclosing block/file sub f { my $inner = 2; # visible only inside f return $outer + $inner; } sub next_id { state $id = 0; # initialized once, persists across calls return ++$id; # state needs use v5.10+ or use feature 'state' }
local and Dynamic Scope
local gives a package global (usually a special variable) a temporary value that is restored when the enclosing scope exits.
{
local $/; # slurp mode inside this block only
my $content = <$fh>;
}
{
local $ENV{TZ} = 'UTC'; # works on hash/array elements too
run_report();
}wantarray and Context
my @all = get_items(); # list context my $n = @items; # array in scalar context yields its length my $count = () = $s =~ /x/g; # count matches via forced list context sub flexible { return wantarray ? (1, 2, 3) : "scalar"; # wantarray: true in list context, false in scalar, undef in void }
Exceptions
# classic: eval + $@ (works everywhere) my $result = eval { risky() }; if ($@) { warn "failed: $@"; # check $@ immediately after eval } die "no config file\n"; # trailing \n suppresses "at line N" die { code => 404 }; # die with a ref for structured errors
Native try/catch blocks are stable since Perl 5.40 (on 5.34-5.38 add use feature 'try'; no warnings 'experimental::try';):
use v5.40; try { risky(); } catch ($e) { warn "failed: $e"; }
Try::Tiny from CPAN works on any Perl:
use Try::Tiny; try { risky(); } catch { warn "failed: $_"; # the error is in $_ } finally { cleanup(); }; # trailing semicolon required