Perl Cheatsheet

References, Packages, and Modules

Use this Perl reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

References

my @nums = (1, 2, 3);
my %user = (name => "Ada", score => 99);

my $array_ref = \@nums;
my $hash_ref = \%user;

print $array_ref->[0];       # 1
print $hash_ref->{name};     # Ada

Anonymous Data

my $nums = [1, 2, 3];
my $user = { name => "Ada", score => 99 };
my $rows = [
    { name => "Ada", score => 99 },
    { name => "Grace", score => 100 },
];

Dereferencing

for my $n (@$nums) { print "$n\n"; }
for my $key (keys %$user) { print "$key\n"; }

push @$nums, 4;
$user->{active} = 1;

Postfix Dereference

Standard since Perl 5.24 and often clearer than the sigil-prefix forms.

my @copy = $array_ref->@*;         # same as @$array_ref
my %copy = $hash_ref->%*;          # same as %$hash_ref
my $last_index = $array_ref->$#*;  # same as $#$array_ref
my @slice = $array_ref->@[0, 2];   # array slice through a ref
my @vals = $hash_ref->@{qw(name score)};  # hash slice through a ref

Passing Collections to Subs

sub average {
    my ($nums) = @_;
    my $sum = 0;
    $sum += $_ for @$nums;
    return $sum / @$nums;
}

Core Modules

use List::Util qw(sum max min first any all);
use JSON::PP qw(encode_json decode_json);
use File::Basename qw(basename dirname);
use Getopt::Long qw(GetOptions);
use FindBin qw($Bin);

my $total = sum(1, 2, 3);
my $json = encode_json({ ok => 1 });

Module Import Style

use Module qw(function_one function_two);  # import only what you use
use lib 'lib';                             # add local module path
use lib "$Bin/lib";                       # path next to current script

Minimal Package

package My::Math;
use v5.36;
use Exporter 'import';

our @EXPORT_OK = qw(add);

sub add ($x, $y) {
    return $x + $y;
}

1;                                      # modules must return true

Avoid my ($a, $b) in helper subs: $a and $b are the package globals sort uses, and lexical shadows break sort { $a <=> $b } in the same scope.

Loading Local Modules

# lib/My/Math.pm defines package My::Math
use FindBin qw($Bin);
use lib "$Bin/lib";
use My::Math qw(add);

print add(2, 3), "\n";

Simple Objects With bless

package Counter;

sub new   { bless { n => 0 }, shift }
sub inc   { ++$_[0]->{n} }
sub value { $_[0]->{n} }

package main;
my $c = Counter->new;
$c->inc;
print $c->value, "\n";

OO With Moo

Moo (lightweight) and Moose (full-featured) from CPAN are the standard object systems for production code.

package Counter;
use Moo;

has n => (is => 'rw', default => 0);

sub inc {
    my ($self) = @_;
    $self->n($self->n + 1);
}

package main;
my $c = Counter->new(n => 10);
$c->inc;
print $c->n, "\n";           # 11

Native class Feature (Experimental)

Perl 5.38 added built-in class/field/method syntax. It is still marked experimental (Perl 5.40 added :reader accessors and __CLASS__).

use v5.38;
use experimental 'class';

class Point {
    field $x :param = 0;
    field $y :param = 0;

    method coords { return ($x, $y) }
}

my $p = Point->new(x => 3, y => 4);
my ($px, $py) = $p->coords;

Module Gotchas

  • use loads at compile time; require loads at run time.
  • File path and package name should line up: lib/My/Thing.pm for My::Thing.
  • Import lists keep namespaces readable; avoid exporting by default in shared modules.