Skip to content
Volume P · The TensorCore.si Library

Perl

The Swiss Army chainsaw of text.

Perl is a scripting language famous for text processing and regular expressions. It powered the early web, still runs many system administration and bioinformatics scripts, and its regex syntax became the standard used by Python, JavaScript and almost every modern language.

Prologue

Why learn Perl?

Perl is still the fastest way to write a one-line fix for messy text, and many companies have Perl code that needs maintaining.

  • Regex power: regular expressions are built into the syntax.
  • One-liners: clean huge log or data files straight from the terminal.
  • CPAN: one of the oldest and largest package archives.
Prologue

Set up and run your first program

Perl is preinstalled on most Linux and macOS systems. On Windows, install Strawberry Perl.

terminal
perl -v
perl hello.pl
cpanm JSON::PP
hello.pl
use strict;
use warnings;
my $name = "Ada";
print "Hello, AI! Welcome to Perl, $name.\n";
TipAlways start scripts with use strict; and use warnings; to catch mistakes.
Chapter 1

Scalars, arrays and hashes

The sigil shows the type: $ for a single value, @ for an array and % for a hash (dictionary). Declare variables with my.

variables.pl
use strict; use warnings;
my $layers = 32;
my @gpus = ("H100", "H200", "B200");
my %vram = (H100 => 80, H200 => 141, B200 => 180);
print "First GPU: $gpus[0]\n";
print "H200 has $vram{H200} GB\n";
print "GPU count: ", scalar(@gpus), "\n";
printf "FP16 size: %.1f GB\n", 8.03e9 * 2 / 1e9;
Chapter 2

Control flow

Perl has the usual if, while and foreach, plus unless and handy statement modifiers like print ... if ....

control.pl
use strict; use warnings;
my %vram = (H100 => 80, H200 => 141, "RTX 5090" => 32);
foreach my $gpu (sort keys %vram) {
    my $gb = $vram{$gpu};
    if ($gb >= 100) { print "$gpu: huge\n" }
    elsif ($gb >= 80) { print "$gpu: large\n" }
    else { print "$gpu: consumer\n" }
}
print "done\n" unless 0;
Chapter 3

Regular expressions

=~ applies a regex. m// matches, s/// substitutes and capture groups land in $1, $2 and so on.

regex.pl
use strict; use warnings;
my $log = "2026-11-11 step=1200 loss=1.873 lr=0.0003";
if ($log =~ /step=(\d+)\s+loss=([\d.]+)/) {
    print "step $1, loss $2\n";
}
(my $clean = "  Tensor   Cores  ") =~ s/\s+/ /g;
print "[$clean]\n";
my @nums = ($log =~ /(\d+\.\d+)/g);
print "@nums\n";
Chapter 4

Subroutines and references

Subroutines receive arguments in @_. References (\@array, \%hash) let you build nested data structures.

subs.pl
use strict; use warnings;
sub params {
    my ($layers, $width) = @_;
    $width //= 4096;
    return 12 * $layers * $width ** 2;
}
my $model = { name => "llama3.1", sizes => [8, 70, 405] };
print params(32), "\n";
print "$model->{name}: @{ $model->{sizes} }\n";
Chapter 5

Files and one-liners

Reading files line by line is simple, and the -n, -p, -e and -i flags turn Perl into a powerful command-line tool.

files.pl
use strict; use warnings;
my %count;
open(my $fh, "<", "notes.txt") or die "Cannot open: $!";
while (my $line = <$fh>) {
    $count{lc $_}++ for $line =~ /(\w+)/g;
}
close $fh;
for my $w ((sort { $count{$b} <=> $count{$a} } keys %count)[0..4]) {
    print "$w $count{$w}\n" if defined $w;
}
# One-liner: average loss from a training log
# perl -ne '$s+=$1,$n++ if /loss=([\d.]+)/; END{print $s/$n,"\n"}' train.log
Part II · AI with Perl

AI with Perl

Perl is not used to train models, but it is excellent for preparing training data: cleaning text, extracting fields from logs and converting formats. It can also call LLM APIs with HTTP::Tiny, which ships with Perl.

The essential libraries

HTTP::TinyHTTP client included with Perl.
JSON::PPJSON encoding and decoding, included with Perl.
PDLPerl Data Language for fast numerical arrays.
AI::MXNet / AI::TensorFlowOlder bindings to ML frameworks.

Clean text for a training dataset

Normalise whitespace, strip HTML and remove duplicate lines: a common data-prep step.

clean.pl
use strict; use warnings;
my %seen;
while (my $line = <STDIN>) {
    $line =~ s/<[^>]+>//g;          # strip HTML tags
    $line =~ s/\s+/ /g;             # normalise whitespace
    $line =~ s/^ | $//g;
    next if length($line) < 20;     # drop very short lines
    next if $seen{lc $line}++;      # drop duplicates
    print "$line\n";
}
# perl clean.pl < raw.txt > clean.txt
Part III · Build an AI agent

Build an AI agent in Perl

HTTP::Tiny and JSON::PP both ship with Perl, so this tool-calling agent needs no extra modules.

Your goal→Model plans→Tool call→Your code runs the tool→Result back to model→Final answer
agent.pl
use strict; use warnings;
use HTTP::Tiny; use JSON::PP;
my $json = JSON::PP->new->utf8;
my $http = HTTP::Tiny->new;
my $url  = "http://localhost:11434/v1/chat/completions";
my $tools = [{ type => "function", function => { name => "get_weather", description => "Weather for a city",
  parameters => { type => "object", properties => { city => { type => "string" } }, required => ["city"] } } }];
my @messages = ({ role => "user", content => "Should I take an umbrella in Lahore today?" });

sub get_weather { my ($a) = @_; return "It is 24°C and sunny in $a->{city}." }

for my $round (1 .. 5) {
    my $res = $http->post($url, { headers => { "Content-Type" => "application/json" },
        content => $json->encode({ model => "llama3.1", messages => \@messages, tools => $tools }) });
    die "HTTP $res->{status}" unless $res->{success};
    my $msg = $json->decode($res->{content})->{choices}[0]{message};
    push @messages, $msg;
    my $calls = $msg->{tool_calls} || [];
    unless (@$calls) { print "$msg->{content}\n"; last }
    for my $c (@$calls) {
        my $args = $json->decode($c->{function}{arguments});
        push @messages, { role => "tool", tool_call_id => $c->{id}, content => get_weather($args) };
    }
}

For larger agents, the same loop works with LWP::UserAgent or Mojo::UserAgent for async requests.

Run it locallyInstall Ollama, run ollama pull llama3.1, and keep it running. The code talks to its OpenAI-compatible API at http://localhost:11434/v1, so the same program also works with vLLM, llama.cpp server or a cloud API by changing the URL, model name and adding an API key.
Part IV · Your path

Perl learning roadmap

Tick items off as you go. Your progress is saved in this browser.

Beginner

Intermediate

Advanced

Part IV · Your path

Projects to build

Log analyserSummarise errors and response times from server logs.
CSV converterTurn messy CSV into clean JSON Lines.
Dataset cleanerDeduplicate and filter text for fine-tuning.
Reference

Perl cheat sheet

TaskSyntax
Scalarmy $x = 5;
Arraymy @a = (1, 2, 3);
Hashmy %h = (k => "v");
Matchif ($s =~ /(\d+)/) { print $1 }
Replace$s =~ s/old/new/g;
One-linerperl -ne 'print if /error/' log
Reference

Common mistakes

  • Forgetting use strict; lets typos create new variables silently.
  • Use eq and ne to compare strings, and == only for numbers.
  • Accessing one array element uses $: $arr[0], not @arr[0].
Reference

Where to go next

On TensorCore.si: Bash volume, Python volume.

Keyboard: [ previous language · ] next language · / search the library