Fork me on GitHub

Project Notes

#441 About Perl

An overview of the Perl programming language, its features, and ecosystem. Includes setting up and running on macOS.

Perl In a Nutshell

Perl is:

  • A high-level, general-purpose programming language created by Larry Wall in 1987
  • Designed for text processing, system administration, and scripting, with strong roots in Unix culture
  • Known for its philosophy: “There’s more than one way to do it” (TMTOWTDI)
  • Both an interpreted language and a glue language—excellent for connecting systems and automating workflows
  • Dynamically typed, with flexible syntax that allows concise but sometimes cryptic code
  • Still widely used in legacy systems, bioinformatics, and DevOps tooling

Perl has:

  • Powerful text manipulation features, especially via built-in regular expressions (one of its defining strengths)
  • Multiple programming paradigms: procedural, object-oriented, and some functional support
  • A rich standard library plus a massive external ecosystem via CPAN (tens of thousands of modules)
  • Context-sensitive behavior (scalar vs list context) that influences how expressions are evaluated
  • Flexible data structures: arrays, hashes (associative arrays), and references for complex structures
  • Strong support for file handling, process control, and system interaction
  • Built-in features for one-liners and quick scripting (commonly used in shell pipelines)
  • A reputation for readability trade-offs—can be extremely concise but harder to maintain without discipline

Perl is governed by:

  • An open-source development model led historically by Larry Wall and now by the Perl Steering Council
  • A global, long-standing community centered around CPAN contributors, mailing lists, and conferences like The Perl Conference
  • A culture that values pragmatism, expressiveness, and developer freedom over strict uniformity
  • Ongoing evolution through modern versions (Perl 5.x), with improvements in performance, maintainability, and tooling
  • A sixth version of Perl was in development, but it was renamed Raku and now managed as a separate language

Why Perl?

  • Unmatched text-processing power — best-in-class regular expressions and string handling make it ideal for parsing logs, data munging, and report generation
  • Rapid scripting and prototyping — minimal boilerplate, easy one-liners, and fast turnaround for small tools and automation
  • “Glue language” strength — excels at stitching together systems, shell commands, and disparate tools
  • Huge module ecosystem via CPAN — mature, battle-tested libraries for almost anything
  • Strong Unix integration — natural fit for sysadmin tasks, pipelines, cron jobs, and infrastructure scripting
  • Flexibility and expressiveness — multiple ways to solve a problem (TMTOWTDI), allowing highly concise solutions
  • Backward compatibility — Perl code from years ago often still runs today with minimal changes
  • Good for legacy systems — many enterprises still rely on Perl; valuable for maintenance and refactoring work
  • Solid performance for scripting tasks — faster than many interpreted languages in text-heavy workloads
  • Mature and stable — decades of real-world use mean fewer surprises in production
  • Niche strengths — particularly strong in bioinformatics, log analysis, and ETL-style data processing
  • Low barrier to entry (for basics) — simple scripts are easy to start, even if mastery takes time

Why not Perl?

  • Readability issues — highly expressive syntax can become cryptic (“write-only code”) without strict discipline
  • Inconsistent style — the TMTOWTDI philosophy leads to many different ways to solve the same problem, making team codebases harder to standardize
  • Declining popularity — fewer new projects and a smaller talent pool compared to languages like Python, Go, or JavaScript
  • Ecosystem aging — while CPAN is vast, some modules are outdated or inconsistently maintained
  • Modern tooling gaps — weaker support for IDEs, linting, formatting, and dependency management compared to newer ecosystems
  • Object-oriented complexity — OO in Perl (especially pre-modern frameworks like Moose/Moo) can feel bolted-on and less intuitive
  • Harder onboarding — steep learning curve for reading idiomatic code, even if writing simple scripts is easy
  • Community contraction — smaller and aging community, fewer new learning resources and discussions
  • Competition from better-specialized tools
    • Python for general scripting and data work
    • Go for systems and DevOps tooling
    • Rust for performance-critical work
  • Performance limits — fine for scripting, but not ideal for CPU-intensive or large-scale concurrent systems
  • Perception problem — often seen as “legacy tech,” which can affect hiring, long-term maintainability, and stakeholder confidence

Running Perl on macOS

macOS ships with a system Perl (e.g. /usr/bin/perl). It is old and managed by Apple. Don’t modify it — you can break system tools.

$ which perl
/usr/bin/perl
$ perl -v

This is perl 5, version 34, subversion 1 (v5.34.1) built for darwin-thread-multi-2level

Installing and maintaining a newer version of Perl is best done with the Perl homebrew formula:

$ brew install perl
...
By default non-brewed cpan modules are installed to the Cellar. If you wish
for your modules to persist across updates we recommend using `local::lib`.

You can set that up like this:
  PERL_MM_OPT="INSTALL_BASE=$HOME/perl5" cpan local::lib
And add the following to your shell profile e.g. ~/.profile or ~/.zshrc
  eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib=$HOME/perl5)"

$ which perl
/opt/homebrew/bin/perl
$ perl -v

This is perl 5, version 42, subversion 2 (v5.42.2) built for darwin-thread-multi-2level

The brew version of Perl will be used as long as /opt/homebrew/bin is prefixed to the PATH environment variable.

Using cpan to install modules from CPAN:

$ cpan JSON
...
  MLEHMANN/JSON-XS-4.04.tar.gz
  /usr/bin/make install  -- OK

Using cpanm to install modules from CPAN:

$ brew install cpanminus
...
$ cpanm JSON
JSON is up to date. (4.11)

A 🐪 Perl Cheat-sheet

Basic Structure

#!/usr/bin/perl
use strict;
use warnings;

print "Hello, world\n";

Variables

my $scalar = 42;          # single value
my @array  = (1, 2, 3);   # ordered list
my %hash   = (a => 1, b => 2);  # key-value pairs
  • Sigils define type: $ (scalar), @ (array), % (hash)

Context (Important!)

my @a = (1,2,3);
my $count = @a;   # scalar context → 3
my @copy  = @a;   # list context → (1,2,3)

Control Flow

if ($x > 10) {
    print "big\n";
} elsif ($x > 5) {
    print "medium\n";
} else {
    print "small\n";
}

for my $i (1..5) {
    print "$i\n";
}

while (<STDIN>) {
    print if /error/;
}

Strings & Interpolation

my $name = "Paul";
print "Hello $name\n";   # interpolates

print 'Hello $name\n';   # literal

Regular Expressions (Core Strength)

$_ = "hello 123";

if (/(\d+)/) {
    print "Found number: $1\n";
}

s/hello/hi/;     # substitution
tr/a-z/A-Z/;     # transliteration

Arrays & Hashes

# Arrays
push @a, 4;
pop @a;
my $first = $a[0];

# Hashes
$hash{key} = "value";
print $hash{key};

for my $k (keys %hash) {
    print "$k => $hash{$k}\n";
}

Subroutines

sub add {
    my ($a, $b) = @_;
    return $a + $b;
}

print add(2, 3);

File Handling

open my $fh, '<', 'file.txt' or die $!;
while (<$fh>) {
    print;
}
close $fh;

One-Liners (Very Perl)

perl -ne 'print if /error/' logfile.txt
perl -pe 's/foo/bar/g' file.txt

Useful Built-ins

chomp($line);     # remove newline
split /,/, $str;  # string → list
join ",", @a;     # list → string
map { $_ * 2 } @a;
grep { $_ > 10 } @a;

Modules & Packages

use strict;
use warnings;
use Data::Dumper;

print Dumper(\%hash);
  • Install from CPAN:
cpan Some::Module

Object-Oriented (Minimal Example)

package MyClass;

sub new {
    my $class = shift;
    return bless {}, $class;
}

sub hello {
    print "Hello\n";
}

1;

Command-Line Arguments

my @args = @ARGV;
print "First arg: $args[0]\n";

Special Variables

$_    # default variable
@_    # subroutine args
$.    # line number
$!    # last error

Credits and References

About LCK#441
PerlmacOS

This page is a web-friendly rendering of my project notes shared in the LittleCodingKata GitHub repository.

Project Source on GitHub Return to the LittleCodingKata Catalog
About LittleCodingKata

LittleCodingKata is my collection of programming exercises, research and code toys broadly spanning things that relate to programming and software development (languages, frameworks and tools).

These range from the trivial to the complex and serious. Many are inspired by existing work and I'll note credits and references where applicable. The focus is quite scattered, as I variously work on things new and important in the moment, or go back to revisit things from the past.

This is primarily a personal collection for my own edification and learning, but anyone who stumbles by is welcome to borrow, steal or reference the work here. And if you spot errors or issues I'd really appreciate some feedback - create an issue, send me an email or even send a pull-request.

Follow the Blog follow projects and notes as they are published in your favourite feed reader