⭐ Complete Master Guide

The most comprehensive, step-by-step Perl programming guide covering syntax, file handling, regex, web scraping, databases, OOP, automation and real-world projects.

Instructor: Mustafa Developer
Level: Beginner → Expert
Covers: Perl 5 (Latest Stable)
Topics: 30+ Lessons

Chapter 01

What is Perl? A Complete History & Introduction

Perl (Practical Extraction and Reporting Language) is a high-level, general-purpose, interpreted scripting language that was created in 1987 by Larry Wall. Wall, a programmer and linguist, originally designed Perl as a flexible, powerful tool for text processing and system administration tasks that were cumbersome to do in existing tools like awk and sed.

Since its inception, Perl has evolved through multiple major versions. Perl 5, released in 1994, remains the most widely used version to this day. It introduced many modern programming features including objects, references, and modules. Perl 5 is still actively maintained and widely deployed across enterprises, universities, and cloud infrastructure worldwide.

In 2000, the community began planning Perl 6 as a complete redesign of the language. However, it eventually diverged so significantly that it was renamed Raku in 2019 and became its own separate language. Meanwhile, Perl 5 continues to thrive independently.

🧬 The DNA of Perl

Perl was heavily influenced by several languages including C, sed, awk, shell scripting, and even natural languages. Larry Wall, who had a background in linguistics, intentionally designed Perl to be expressive and flexible — often summarized by the phrase “There is more than one way to do it” (TIMTOWTDI). This philosophy stands in contrast to Python’s “There should be one obvious way to do it.”

📅

Created In

1987 by Larry Wall, a programmer and linguist who wanted better text processing tools.

⚙️

Current Version

Perl 5.38+ is the latest stable release, actively maintained by the Perl community.

🌍

Cross-Platform

Runs natively on Windows, macOS, Linux, Unix, BSD and many other operating systems.

🆓

Open Source

Free and open source under the Artistic License or GNU GPL. No licensing costs ever.


Chapter 02

Why Learn Perl? Key Use Cases & Industries

Perl is sometimes called the “Swiss Army Knife of programming languages” — and for good reason. Its unmatched power in text processing, combined with a rich ecosystem of CPAN modules and cross-platform compatibility, makes it a uniquely versatile tool. Here is why developers still actively choose Perl in 2024 and beyond:

🏭 Industries That Rely on Perl

Perl is not just a hobbyist language — it powers some of the world’s most critical infrastructure:

Industry Perl Use Case Notable Users
Cybersecurity Log analysis, packet inspection, exploit scripting, threat hunting Security firms, pentesters
Finance Automated trading, log analysis, data pipeline automation Stock exchanges, hedge funds
Bioinformatics DNA sequence processing, genome data parsing, research pipelines NASA, research labs
Web Hosting / SaaS Backend scripting, automation, cron job management Amazon, Booking.com
System Administration Linux server management, file processing, network monitoring Data centers, ISPs

💡 Why Perl Still Matters

🔤

Powerful Text Processing

Perl has built-in, natively supported regular expressions — arguably the most powerful in any mainstream language. It is the gold standard for log parsing, data extraction and format transformation.

🤖

Automation & Scripting

Used in system administration, batch processing and cron jobs. Perl can automate virtually any repetitive computing task with concise, expressive code.

🌐

Web Scraping & APIs

Modules like LWP::UserAgent and HTML::TreeBuilder make Perl a powerful engine for scraping websites, extracting structured data and interacting with RESTful APIs.

🗄️

Database Interaction

Through DBI (Database Interface), Perl works seamlessly with MySQL, PostgreSQL, SQLite, Oracle and virtually any SQL database with minimal driver changes.

📦

CPAN Ecosystem

CPAN (Comprehensive Perl Archive Network) hosts over 200,000+ modules covering everything from email sending to machine learning wrappers.

🔄

Legacy Code

Billions of lines of production Perl power existing infrastructure. Knowing Perl is essential for maintaining, extending and modernizing these critical systems.


Chapter 03

📥 Complete Perl Installation Guide

Before you can write your first Perl program, you need to install the Perl interpreter on your system. This section covers every platform: Windows (32-bit & 64-bit), macOS, Linux (all major distros), and Termux (Android).

✅ Pro Tip: Check if Perl is Already Installed Open your terminal or command prompt and run the following command. If Perl is already installed, you will see the version number.
Shell / CMD
perl -v

If you see output like This is perl 5, version 38... then Perl is already installed and you can skip to the next section. If not, follow the appropriate guide below.

🪟

Windows Installation (32-bit & 64-bit)

On Windows, you have two excellent options for installing Perl. We recommend Strawberry Perl for most users because it is free, open-source, includes all necessary build tools and is the most complete Perl distribution for Windows.

Option A: Strawberry Perl (Recommended — Free & Open Source)

1
Visit the Official Website Go to strawberryperl.com in your browser. This is the official and safest source for Strawberry Perl.
2
Choose Your Architecture Download the correct version for your system:
64-bit Windows (Recommended): Download strawberry-perl-X.X.X-64bit.msi
32-bit Windows: Download strawberry-perl-X.X.X-32bit.msi
Choose the .msi installer for simplest installation.
3
Run the Installer Double-click the downloaded .msi file. Click Next, accept the license terms, choose your installation directory (default is fine), and click Install.
4
Verify Installation Open a new Command Prompt (important: must be a new window) and type:
Windows CMD
perl -v

Expected output: This is perl 5, version 40, subversion 0 (v5.40.0) built for MSWin32-x64-multi-thread

Option B: ActivePerl (Enterprise Use)

ActivePerl by ActiveState is a commercial-grade Perl distribution commonly used in enterprise environments. It includes a state-of-the-art package manager and commercial support. Download from activestate.com/products/perl. Follow the wizard-based installer. Verify with perl -v after installation.

⚠️ Important for Windows Users After installation, always open a new Command Prompt or PowerShell window — existing windows won’t have the updated PATH variable and will not recognize the perl command.

Checking 32-bit vs. 64-bit on Windows

Windows CMD
# Check system architecture
wmic os get osarchitecture

# Then verify Perl architecture after install
perl -e "use Config; print $Config{archname};"

For 64-bit systems you will see MSWin32-x64-multi-thread. For 32-bit systems: MSWin32-x86-multi-thread.

🍎

macOS Installation

macOS ships with a system Perl pre-installed. However, Apple’s built-in Perl may be an older version and should not be used for development. It is highly recommended to install a fresh, independent Perl using Homebrew.

1
Check Built-in Perl Version Open Terminal (Applications → Utilities → Terminal) and run:
macOS Terminal
perl -v
If this is sufficient (usually Perl 5.30 or 5.34 on modern Macs), you can proceed. Otherwise, continue below.
2
Install Homebrew (if not already installed)
macOS Terminal
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
3
Install the Latest Perl via Homebrew
macOS Terminal
brew install perl
4
Add Homebrew Perl to PATH
macOS Terminal (Bash / Zsh)
# For Zsh (default on macOS Catalina+)
echo 'export PATH="$(brew --prefix)/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

# For Bash
echo 'export PATH="$(brew --prefix)/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
5
Verify Installation
macOS Terminal
perl -v
which perl
# Should show /usr/local/bin/perl or /opt/homebrew/bin/perl (NOT /usr/bin/perl)
📝 Apple Silicon (M1/M2/M3 Macs) On Apple Silicon Macs, Homebrew installs to /opt/homebrew. The Homebrew Perl is a native ARM64 binary — you do not need Rosetta for Perl on M-series Macs.
🐧

Linux Installation (Ubuntu, Debian, Fedora, Arch, openSUSE)

Most Linux distributions ship with Perl pre-installed. However, if you need the latest version or Perl is missing, use your distribution’s package manager.

Ubuntu / Debian / Linux Mint (apt)

Ubuntu / Debian Terminal
# Update package lists
sudo apt update

# Install Perl
sudo apt install perl

# Optional: Install build tools for CPAN modules
sudo apt install build-essential libssl-dev

# Verify installation
perl -v

Fedora / RHEL / CentOS / Rocky Linux (dnf / yum)

Fedora / RHEL Terminal
# Install Perl
sudo dnf install perl

# For older RHEL/CentOS systems using yum:
sudo yum install perl

# Verify
perl -v

Arch Linux / Manjaro (pacman)

Arch Linux Terminal
# Install Perl
sudo pacman -S perl

# Verify
perl -v

openSUSE / SUSE Linux (zypper)

openSUSE Terminal
# Install Perl
sudo zypper install perl

# Verify
perl -v

Installing the Latest Perl via perlbrew (All Linux Distros)

perlbrew allows you to install and manage multiple Perl versions on the same Linux machine — similar to nvm for Node.js or pyenv for Python. This is the recommended approach for developers who need a specific Perl version.

Linux Terminal (perlbrew)
# Install perlbrew
\curl -L https://install.perlbrew.pl | bash

# Add perlbrew to your shell profile
echo 'source ~/perl5/perlbrew/etc/bashrc' >> ~/.bashrc
source ~/.bashrc

# Install latest stable Perl
perlbrew install perl-5.38.0

# Switch to the installed version
perlbrew switch perl-5.38.0

# Verify
perl -v
✅ Tip: 32-bit vs. 64-bit on Linux The system package manager will automatically install the correct architecture version. To verify which architecture your Perl was compiled for, run: perl -e "use Config; print $Config{archname};"
📱

Termux Installation (Android)

Termux is a powerful Android terminal emulator that gives you a full Linux-like environment on your phone or tablet. You can install Perl on Termux and write real Perl scripts on Android.

1
Install Termux Download Termux from the F-Droid store (recommended) or the Google Play Store. The F-Droid version is more up-to-date.
2
Update Termux Packages
Termux
pkg update && pkg upgrade
3
Install Perl
Termux
pkg install perl
4
Install CPAN and Build Tools
Termux
pkg install build-essential
cpan App::cpanminus
5
Verify Installation
Termux
perl -v
📝 Termux Architecture Note Modern Android devices are 64-bit (ARM64). Termux automatically installs the ARM64 version of Perl. You can verify: uname -m — this should return aarch64 for 64-bit ARM.

🛠️ Setting Up Your Code Editor

While you can technically write Perl in any text editor (even Notepad), using a proper code editor dramatically improves productivity with syntax highlighting, auto-completion and integrated terminals.

Recommended: Visual Studio Code (VS Code) — Download from code.visualstudio.com. After installing, add the Perl extension by searching “Perl” in the Extensions panel. Install the extension by Gerald Richter or Marc Auberer for syntax highlighting and IntelliSense.

On Linux or macOS, vim and emacs are excellent alternatives with powerful Perl support via plugins. For a GUI alternative on Linux, Geany or Kate work very well.


Chapter 04

✍️ Writing & Running Your First Perl Script

Now that Perl is installed, let’s write and execute your first Perl program. Create a new file called hello.pl (the .pl extension is the standard convention for Perl scripts).

Perl — hello.pl
#!/usr/bin/perl
# This is the shebang line — tells the OS to use Perl interpreter

use strict;    # Enforces good coding practices
use warnings; # Helps catch potential errors early

print "Hello, Perl!\n"; # \n = newline character

Running Your Script

🪟 Windows CMD
CMD
cd Desktop\perl
perl hello.pl
🍎 macOS / 🐧 Linux
Terminal
chmod +x hello.pl
./hello.pl
# OR
perl hello.pl
📱 Termux
Termux
perl hello.pl

Expected Output: Hello, Perl!

✅ Success! If you see “Hello, Perl!” in your terminal, your Perl environment is correctly set up and you are ready to continue learning.

Chapter 05

📐 Perl Basic Syntax & Program Structure

Understanding the structure of a Perl program is fundamental to writing clean, efficient code. Every Perl script follows a consistent anatomy:

Perl — Anatomy of a Perl Script
#!/usr/bin/perl         # 1. Shebang Line — tells OS which interpreter to use

use strict;              # 2. Directives — enforces safe coding practices
use warnings;            # 2. Directives — enables helpful runtime warnings

# 3. Single-line comment (starts with #)

=pod
  4. Multi-line comment block (POD — Plain Old Documentation)
  This block is ignored by the Perl compiler.
=cut

# 5. Statements — end with semicolons
my $name = "Chandan Kumar";
print "Hello, $name!\n";  # Variable interpolation in double quotes

# 6. Block structures — grouped with curly braces
if (1 == 1) {
    print "Conditional block executed.\n";
}

Key Syntax Rules

RuleDescriptionExample
Semicolon terminationEvery statement must end with ;print "hi";
Case sensitivityPerl is case-sensitive — $Name$namemy $Name = "A"; my $name = "B";
Shebang lineFirst line, tells OS to use Perl. Required on Unix/Linux.#!/usr/bin/perl
CommentsSingle line with #, multi-line with POD blocks# This is a comment
BlocksCode grouped in curly braces { }if ($x) { ... }
IndentationNot required but strongly recommended for readability4 spaces per indent level

Chapter 06

📊 Data Types: Scalars, Arrays & Hashes

Perl has three fundamental data types that serve as the building blocks for all data manipulation. Understanding these thoroughly is essential to becoming proficient in Perl.

1. Scalar Variables ($)

A scalar variable stores a single value — a string, a number, a floating-point value, or a reference. Scalar variables always start with the dollar sign $.

Perl — Scalar Variables
use strict;
use warnings;

# String scalar
my $name  = "Chandan Kumar";

# Integer scalar
my $age   = 30;

# Floating-point scalar
my $price = 9.99;

# Boolean-like (Perl uses 1 for true, '' or 0 for false)
my $is_active = 1;

print "Name:  $name\n";
print "Age:   $age\n";
print "Price: $price\n";

2. Arrays (@)

An array stores an ordered list of scalar values. Arrays start with the @ symbol. Elements are accessed using a dollar sign with square bracket indexing (zero-based).

Perl — Arrays
use strict;
use warnings;

# Declare an array
my @colors = ("red", "green", "blue");

# Access by index (zero-based)
print $colors[0] . "\n";  # red
print $colors[2] . "\n";  # blue
print $colors[-1] . "\n"; # blue (last element)

# Common array operations
push @colors, "yellow";    # Add to end
my $removed = pop @colors; # Remove from end
unshift @colors, "white"; # Add to beginning
my $first = shift @colors; # Remove from beginning

# Array size
my $size = scalar @colors;
print "Array size: $size\n";

# Print all elements
print "All colors: @colors\n";

3. Hashes (%)

A hash stores key-value pairs (similar to dictionaries in Python or objects in JavaScript). Hashes use the % sigil. Values are accessed with curly braces and the key name.

Perl — Hashes
use strict;
use warnings;

# Declare a hash
my %person = (
    'name' => "Chandan Kumar",
    'age'  => 30,
    'city' => "Pune",
);

# Access a value by key
print "Name: $person{'name'}\n";
print "Age:  $person{'age'}\n";

# Add a new key-value pair
$person{'job'} = "Software Developer";

# Check if a key exists
if (exists $person{'job'}) {
    print "Job: $person{'job'}\n";
}

# Delete a key
delete $person{'city'};

# Iterate over all key-value pairs
while (my ($key, $val) = each %person) {
    print "$key => $val\n";
}
Data TypeSigilStoresAccess Example
Scalar$Single value (string, number, reference)$name
Array@Ordered list of scalars$colors[0]
Hash%Unordered key-value pairs$person{'name'}

Chapter 07

🔢 Operators in Perl

Perl provides a rich set of operators for performing arithmetic, comparison, logical and string operations. Here is a comprehensive reference:

Arithmetic Operators

Perl — Arithmetic Operators
my $a = 10;
my $b = 3;

print $a + $b;   # Addition:       13
print $a - $b;   # Subtraction:    7
print $a * $b;   # Multiplication: 30
print $a / $b;   # Division:       3.333...
print $a % $b;   # Modulus:        1 (remainder)
print $a ** $b;  # Exponentiation: 1000 (10^3)

Comparison Operators

NumericStringMeaning
==eqEqual to
!=neNot equal to
>gtGreater than
<ltLess than
>=geGreater than or equal to
<=leLess than or equal to
<=>cmpThree-way comparison (-1, 0, 1)

String Operators

Perl — String Operators
my $greeting = "Hello";
my $name     = "Chandan";

# Concatenation with dot (.)
print $greeting . " " . $name . "\n"; # Hello Chandan

# Repetition with (x)
print "Hi " x 3;  # Hi Hi Hi

Chapter 08

🔤 String Manipulation & Functions

Perl excels at string processing. Here are the most important string functions you need to know:

Perl — String Functions
use strict;
use warnings;

my $str = "Hello, Perl!";

# Length of string
print length($str) . "\n";       # 12

# Uppercase / Lowercase
print uc($str) . "\n";           # HELLO, PERL!
print lc($str) . "\n";           # hello, perl!
print ucfirst($str) . "\n";      # Hello, Perl! (first char uppercase)
print lcfirst($str) . "\n";      # hello, Perl! (first char lowercase)

# Substring extraction: substr(string, start, length)
print substr($str, 7, 4) . "\n";  # Perl

# Find position of substring: index(string, search)
print index($str, "Perl") . "\n"; # 7

# Replace using substitution (regex s///)  
(my $new = $str) =~ s/Perl/Python/;
print $new . "\n";                # Hello, Python!

# Split a string into an array
my @words = split(/,\s*/, $str);
print "$_\n" for @words;

# Join an array into a string
my $joined = join(" | ", "one", "two", "three");
print $joined . "\n";             # one | two | three

# Reverse a string
print scalar reverse($str) . "\n";

Chapter 09

⌨️ User Input & Output

Perl — STDIN / User Input
use strict;
use warnings;
use feature 'say'; # 'say' adds automatic newline (Perl 5.10+)

print "Enter your name: ";
my $name = <STDIN>;  # Read from standard input
chomp $name;          # Remove trailing newline from input
say "Hello, $name!";

──────────────────────────────────────────
# Simple calculator using user input:
print "Enter first number: ";
my $num1 = <STDIN>;
chomp $num1;

print "Enter second number: ";
my $num2 = <STDIN>;
chomp $num2;

my $sum = $num1 + $num2;
say "Sum: $sum";

Chapter 10

🔀 Conditional Statements

Perl — Conditionals
use strict;
use warnings;

my $marks = 75;

# if / elsif / else
if ($marks >= 90) {
    print "Grade: A\n";
} elsif ($marks >= 75) {
    print "Grade: B\n";
} elsif ($marks >= 50) {
    print "Grade: C\n";
} else {
    print "Grade: F\n";
}

# unless (runs only if condition is FALSE)
my $x = 0;
unless ($x) {
    print "x is false (zero or empty)\n";
}

# Ternary operator: condition ? true_val : false_val
my $age     = 20;
my $message = ($age >= 18) ? "Adult" : "Minor";
print "$message\n"; # Adult

Chapter 11

🔄 Looping Structures

Perl — All Loop Types
## 1. for loop (C-style)
for (my $i = 1; $i <= 5; $i++) {
    print "Count: $i\n";
}

## 2. foreach loop (iterate over array)
my @fruits = ("apple", "banana", "cherry");
foreach my $fruit (@fruits) {
    print "Fruit: $fruit\n";
}

## 3. Range-based for loop
for my $n (1..10) {
    print "$n ";
}
print "\n";

## 4. while loop
my $count = 1;
while ($count <= 5) {
    print "Count: $count\n";
    $count++;
}

## 5. until loop (runs while condition is FALSE)
my $val = 1;
until ($val > 5) {
    print "Val: $val\n";
    $val++;
}

## 6. do-while loop (executes at least once)
my $c = 1;
do {
    print "do-while: $c\n";
    $c++;
} while ($c <= 5);

Chapter 12

⏹️ Loop Control: next, last, redo

Perl — Loop Control Statements
# next — skip current iteration (like 'continue' in other languages)
for my $i (1..10) {
    next if $i % 2 == 0;  # Skip even numbers
    print "$i ";             # Prints: 1 3 5 7 9
}

# last — exit the loop immediately (like 'break' in other languages)
for my $i (1..10) {
    last if $i == 5;  # Stop loop when i reaches 5
    print "$i ";         # Prints: 1 2 3 4
}

# redo — restart current iteration without re-checking condition
# (Use carefully — can create infinite loops!)
my $attempts = 0;
for my $item ("a", "b", "c") {
    $attempts++;
    redo if $item eq "b" && $attempts < 3;
    print "Processing: $item\n";
}

Chapter 13

🧩 Functions & Subroutines

In Perl, functions are called subroutines and are defined using the sub keyword. They are the primary mechanism for code reuse and modular design.

Perl — Subroutines
use strict;
use warnings;

## Basic subroutine
sub greet {
    print "Welcome to Perl Programming!\n";
}
greet();  # Call the subroutine

## Subroutine with parameters (@_ is the default argument array)
sub greet_user {
    my ($first_name, $last_name) = @_;
    print "Hello, $first_name $last_name!\n";
}
greet_user("Chandan", "Kumar");

## Subroutine with return value
sub add {
    my ($n1, $n2) = @_;
    return $n1 + $n2;
}
my $result = add(20, 30);
print "Sum: $result\n";  # Sum: 50

## Default parameter values using shift
sub multiply {
    my $a = shift || 1;  # Default to 1 if not provided
    my $b = shift || 1;
    return $a * $b;
}

## Returning multiple values
sub get_min_max {
    my @numbers = @_;
    my ($min, $max) = ($numbers[0], $numbers[0]);
    foreach my $num (@numbers) {
        $min = $num if $num < $min;
        $max = $num if $num > $max;
    }
    return ($min, $max);  # Return multiple values
}
my ($min_val, $max_val) = get_min_max(10, 4, 20, 8, 15);
print "Min: $min_val, Max: $max_val\n"; # Min: 4, Max: 20

## Recursive function (Factorial)
sub factorial {
    my $n = shift;
    return 1 if $n == 0;
    return $n * factorial($n - 1);
}
print factorial(5) . "\n";  # 120

Chapter 14

🔭 Variable Scope: Global, Lexical & Persistent

Perl — Variable Scope
use strict;
use warnings;
use feature 'state';

## 1. Global scope — declared with 'our'
## Accessible throughout the entire script
our $global_var = "I am global";

sub show_global {
    print $global_var . "\n";  # Accessible here
}

## 2. Lexical scope — declared with 'my'
## Restricted to the enclosing block or subroutine
sub show_lexical {
    my $lex_var = "I am lexical";
    print $lex_var . "\n";  # OK inside this sub
}
# print $lex_var;  # ERROR! Out of scope

## 3. Persistent scope — declared with 'state'
## Retains its value between function calls (like a static variable)
sub counter {
    state $count = 0;  # Initialized only once
    $count++;
    print "Count: $count\n";
}
counter();  # Count: 1
counter();  # Count: 2
counter();  # Count: 3

Chapter 15

🔍 Regular Expressions (Regex) in Perl

Regular expressions are arguably Perl’s most powerful feature. They provide a concise, expressive way to search, match, validate and transform text. Perl’s regex engine is one of the most fully-featured in any programming language.

Basic Pattern Matching

Perl — Regex Matching
use strict;
use warnings;

my $text = "Welcome to Perl Programming!";

# Basic match: =~ operator with m//
if ($text =~ /Perl/) {
    print "Match found!\n";
}

# Case-insensitive match using 'i' flag
if ($text =~ /perl/i) {
    print "Case-insensitive match!\n";
}

# Substitution: s/old/new/
$text =~ s/Perl/Python/;
print $text . "\n";  # Welcome to Python Programming!

# Global substitution (replace all): s/old/new/g
my $str = "apple apple apple";
$str =~ s/apple/orange/g;
print $str . "\n";  # orange orange orange

Meta Characters Reference

Meta CharMeaningExample
.Any character except newline/c.t/ matches “cat”, “cut”, “cot”
^Start of string/^Hello/
$End of string/world$/
\dAny digit (0-9)/\d+/
\wAny word character (a-z, A-Z, 0-9, _)/\w+/
\sWhitespace (space, tab, newline)/\s+/
\DNon-digit/\D+/
\WNon-word character/\W/
*Zero or more times/ab*/
+One or more times/ab+/
?Zero or one time/colou?r/
{n}Exactly n times/\d{3}/
{n,}At least n times/\d{2,}/
{n,m}Between n and m times/\d{2,5}/

Advanced: Lookahead, Lookbehind & Capturing Groups

Perl — Advanced Regex
# Capturing groups — extract parts of a match
my $sentence = "Alice is 25 years old";
if ($sentence =~ /(\w+) is (\d+)/) {
    print "Name: $1, Age: $2\n";  # Name: Alice, Age: 25
}

# Positive lookahead: match 'hello' only if followed by 'world'
my $text = "hello world";
print "Found!\n" if $text =~ /hello(?=\s+world)/;

# Negative lookahead: match 'hello' only if NOT followed by 'world'
print "Found!\n" if $text =~ /hello(?!\s+world)/;

# Email validation regex
my $email = '[email protected]';
if ($email =~ /^[\w.%+\-]+@[\w.\-]+\.[a-zA-Z]{2,}$/) {
    print "Valid email!\n";
}

# Phone number validation (10 digits)
my $phone = "1234567890";
print "Valid phone!\n" if $phone =~ /^\d{10}$/;

Chapter 16

📁 File Handling in Perl

Perl — File Handling
use strict;
use warnings;

## READING a file — line by line (memory efficient)
open(my $fh, '<', 'input.txt') or die "Cannot open file: $!";
while (my $line = <$fh>) {
    chomp $line;
    print $line . "\n";
}
close $fh;

## WRITING to a file (overwrites existing content)
open(my $out, '>', 'output.txt') or die "Cannot write: $!";
print $out "Hello, Perl!\n";
print $out "File writing in Perl is easy.\n";
close $out;

## APPENDING to a file (adds to end, preserves existing content)
open(my $app, '>>', 'output.txt') or die "Cannot append: $!";
print $app "This line is appended.\n";
close $app;
Mode SymbolNameBehavior
'<'ReadOpen existing file for reading only. Error if file doesn’t exist.
'>'WriteCreate file or overwrite if it exists. Destroys existing content.
'>>'AppendCreate file or add to end of existing file. Preserves content.
'+<'Read/WriteOpen existing file for both reading and writing.

Chapter 17

📊 CSV & JSON File Processing

Working with CSV Files

Shell — Install CSV Module
cpan install Text::CSV
Perl — Read CSV File
use strict;
use warnings;
use Text::CSV;

my $csv = Text::CSV->new({ binary => 1 });
open(my $fh, '<', 'data.csv') or die "Cannot open: $!";

# Skip header row
my $header = $csv->getline($fh);

while (my $row = $csv->getline($fh)) {
    print "Name: $row->[0], Age: $row->[1]\n";
}
close $fh;

Working with JSON Files

Shell — Install JSON Module
cpan install JSON
Perl — Read & Write JSON
use strict;
use warnings;
use JSON;

# Perl data structure (hash)
my %data = (
    name  => "Chandan",
    age   => 30,
    city  => "Pune",
);

# Encode Perl hash to JSON string
my $json_str = encode_json(\%data);
print $json_str . "\n";

# Write JSON to file
open(my $fh, '>', 'output.json');
print $fh $json_str;
close $fh;

# Read and decode JSON from file
open(my $in, '<', 'output.json');
my $text = do { local $/; <$in> };
close $in;
my $decoded = decode_json($text);
print "Name: $decoded->{name}\n";

Chapter 18

📦 Perl Modules & CPAN

CPAN (Comprehensive Perl Archive Network) is Perl’s package ecosystem with over 200,000 modules. It is one of the oldest and largest software repositories in the world.

Installing CPAN Modules

Shell — Install CPAN Modules
# Install a module from CPAN
cpan install Module::Name

# Using cpanminus (faster, recommended)
cpanm Module::Name

# Install multiple modules at once
cpanm LWP::UserAgent HTML::TreeBuilder JSON DBI

Creating Your Own Custom Module

Perl — MyModule.pm
## File: MyModule.pm
package MyModule;

use strict;
use warnings;

sub greet {
    my $name = shift;
    return "Hello, $name!";
}

1;  # MUST end with 1 to indicate successful loading
Perl — main.pl (Using Custom Module)
use strict;
use warnings;
use lib '.';  # Tell Perl to look in current directory
use MyModule;

print MyModule::greet("Chandan") . "\n";

Chapter 19

🏗️ Object-Oriented Programming (OOP) in Perl

Perl — Person.pm (OOP Class)
package Person;
use strict;
use warnings;

# Constructor method
sub new {
    my ($class, $name, $age) = @_;
    my $self = {
        name => $name,
        age  => $age,
    };
    return bless $self, $class;  # bless creates the object
}

# Method
sub greet {
    my $self = shift;
    return "Hello, my name is $self->{name} and I am $self->{age} years old.";
}

1;
Perl — main.pl (Using the Class)
use strict;
use warnings;
use lib '.';
use Person;

# Create an object (instance of Person class)
my $person = Person->new("Chandan", 30);
print $person->greet() . "\n";

Chapter 20

🧬 Inheritance & Polymorphism

Perl — Employee.pm (Child Class)
package Employee;
use strict;
use warnings;
use parent 'Person';  # Inherit from Person

sub new {
    my ($class, $name, $age, $job) = @_;
    # Call parent constructor
    my $self = $class->SUPER::new($name, $age);
    $self->{job} = $job;
    return bless $self, $class;
}

# Overriding (Polymorphism) parent method
sub greet {
    my $self = shift;
    my $base = $self->SUPER::greet();
    return $base . " I work as a $self->{job}.";
}

1;

Chapter 21

🗄️ Database Programming with DBI

Perl’s DBI (Database Interface) module provides a consistent API to connect to and query virtually any relational database including MySQL, PostgreSQL and SQLite.

Installation

Shell — Install DBI Drivers
cpan install DBI
cpan install DBD::SQLite    # For SQLite
cpan install DBD::mysql     # For MySQL
cpan install DBD::Pg        # For PostgreSQL

Complete SQLite CRUD Example

Perl — SQLite CRUD
use strict;
use warnings;
use DBI;

# Connect to SQLite database
my $dbh = DBI->connect(
    "DBI:SQLite:dbname=test.db",
    "", "",
    { RaiseError => 1, AutoCommit => 1 }
) or die $DBI::errstr;
print "Connected successfully!\n";

# CREATE TABLE
$dbh->do(q{
    CREATE TABLE IF NOT EXISTS users (
        id    INTEGER PRIMARY KEY AUTOINCREMENT,
        name  TEXT NOT NULL,
        age   INTEGER
    )
});

# INSERT data
my $sth = $dbh->prepare("INSERT INTO users (name, age) VALUES (?, ?)");
$sth->execute("Chandan", 30);
$sth->execute("Ram",     25);

# SELECT and display all rows
my $sel = $dbh->prepare("SELECT id, name, age FROM users");
$sel->execute();
while (my $row = $sel->fetchrow_hashref()) {
    print "ID: $row->{id}  Name: $row->{name}  Age: $row->{age}\n";
}

# UPDATE a record
$dbh->do("UPDATE users SET age = 31 WHERE name = 'Chandan'");

# DELETE a record
$dbh->do("DELETE FROM users WHERE name = 'Ram'");

$dbh->disconnect();
print "Done!\n";

Chapter 22

🕷️ Web Scraping with LWP & HTML::TreeBuilder

Shell — Install Web Scraping Modules
cpan install LWP::UserAgent
cpan install HTML::TreeBuilder
Perl — Web Scraper
use strict;
use warnings;
use LWP::UserAgent;
use HTML::TreeBuilder;

my $url = 'https://www.perl.org';
my $ua  = LWP::UserAgent->new(agent => 'PerlBot/1.0');

my $response = $ua->get($url);

unless ($response->is_success) {
    die "Failed: " . $response->status_line;
}

# Parse the HTML
my $tree = HTML::TreeBuilder->new();
$tree->parse_content($response->decoded_content);

# Extract all hyperlinks
print "=== All Links ===\n";
for my $link ($tree->look_down(_tag => 'a')) {
    my $href = $link->attr('href');
    print "$href\n" if defined $href;
}

$tree->delete;  # Clean up memory

Chapter 23

🌐 Making API Requests in Perl

Perl — REST API GET Request
use strict;
use warnings;
use LWP::UserAgent;
use JSON;

my $url = 'https://jsonplaceholder.typicode.com/posts/1';
my $ua  = LWP::UserAgent->new();
my $res = $ua->get($url);

if ($res->is_success) {
    my $data = decode_json($res->decoded_content);
    print "Title: $data->{title}\n";
    print "Body:  $data->{body}\n";
} else {
    die "API error: " . $res->status_line;
}

Chapter 24

🏗️ Real-World Perl Projects

Project 1: Number Guessing Game

Perl — Number Guessing Game
use strict;
use warnings;
use feature 'say';

my $secret = int(rand(100)) + 1;
say "Guess the number between 1 and 100! You have 10 attempts.";

my $attempts = 0;
while (1) {
    print "Your guess: ";
    my $guess = <STDIN>;
    chomp $guess;
    $attempts++;

    if ($guess == $secret) {
        say "🎉 Congratulations! You guessed it in $attempts attempts!";
        last;
    } elsif ($guess < $secret) {
        say "📈 Too low! Try again.";
    } else {
        say "📉 Too high! Try again.";
    }

    if ($attempts >= 10) {
        say "❌ Game over! The number was $secret.";
        last;
    }
}

Project 2: Log Parser Tool

Perl — Log Parser
use strict;
use warnings;

my $log_file = 'app.log';

sub parse_log {
    my $filter = shift;  # e.g., "ERROR", "WARNING", "INFO"
    open(my $fh, '<', $log_file) or die "Cannot open log: $!";
    while (my $line = <$fh>) {
        print $line if !$filter || $line =~ /$filter/i;
    }
    close $fh;
}

# Search log entries containing a keyword
sub search_log {
    my $keyword = shift;
    print "Search results for '$keyword':\n";
    parse_log($keyword);
}

search_log("ERROR");   # Show only error lines
search_log("backup");  # Search for backup-related entries

Project 3: End-to-End Data Processing (CSV → SQLite → JSON Report)

This complete project demonstrates reading a CSV sales file, inserting data into SQLite, filtering records by price, and generating a JSON report — showcasing Perl’s full power for data pipeline work.

Perl — Data Processing Pipeline
use strict;
use warnings;
use Text::CSV;
use DBI;
use JSON;

# Connect to SQLite
my $dbh = DBI->connect("DBI:SQLite:dbname=sales.db", "", "",
    { RaiseError => 1, AutoCommit => 1 });

# Create table
$dbh->do(q{
    CREATE TABLE IF NOT EXISTS sales (
        order_id TEXT, product TEXT, category TEXT,
        price REAL, quantity INTEGER
    )
});

# Read and insert CSV data
my $csv = Text::CSV->new({ binary => 1 });
open(my $fh, '<', 'sales_data.csv');
$csv->getline($fh);  # Skip header
my $ins = $dbh->prepare("INSERT INTO sales VALUES (?,?,?,?,?)");
while (my $row = $csv->getline($fh)) {
    $ins->execute(@$row);
}
close $fh;

# Filter: price > 1000, generate JSON report
my $sth = $dbh->prepare("SELECT * FROM sales WHERE price > 1000");
$sth->execute();
my @data;
while (my $row = $sth->fetchrow_hashref()) {
    push @data, $row;
}

open(my $out, '>', 'report.json');
print $out encode_json(\@data);
close $out;
print "Report generated: report.json\n";

Chapter 25

✅ Best Practices for Writing Clean Perl Code

#Best PracticeWhy It Matters
1Always use use strict; and use warnings;Prevents undeclared variables, catches runtime errors, enforces discipline
2Declare variables with myCreates lexical (block-scoped) variables, avoids global name collisions
3Follow the DRY principle (Don’t Repeat Yourself)Move repeated code into subroutines or modules for maintainability
4Use meaningful variable and function names$total_price is better than $tp. Code reads like documentation.
5Use prepared statements for database queriesPrevents SQL injection and improves performance via query caching
6Always check file open results with or dieProvides clear error messages instead of cryptic failures
7Use chomp on all user inputRemoves trailing newlines that can cause comparison failures
8Use CPAN modules rather than reinventing the wheelBattle-tested, well-documented, widely used code
9Add comments and POD documentationEssential for code maintainability and team collaboration
10Use eval blocks for error-prone operationsCreates try-catch like error handling for robust scripts

Analysis

✅ Advantages of Perl Programming

✅ Advantages

  • Unmatched Text Processing: Perl’s native regular expression support is the most powerful in any mainstream language. It is the go-to tool for log parsing, data extraction and text transformation at scale.
  • CPAN Ecosystem: Over 200,000 ready-to-use modules covering virtually every domain — from database access to machine learning, email sending, XML parsing and bioinformatics.
  • Cross-Platform Compatibility: A single Perl script runs without modification on Windows, macOS, Linux, Unix and BSD. True write-once-run-anywhere capability.
  • Rapid Development: Perl’s expressive, flexible syntax allows developers to accomplish complex tasks with minimal lines of code compared to more verbose languages.
  • Battle-Tested Stability: Perl 5 has been in continuous production use for over 30 years. It powers critical infrastructure at Amazon, Booking.com, NASA and major financial institutions.
  • Excellent for Automation: From cron job scripting and system administration to file management and batch data processing, Perl excels at automating repetitive tasks.
  • Mature DBI Ecosystem: DBI provides a consistent interface to MySQL, PostgreSQL, SQLite, Oracle and virtually any SQL database with minimal code changes when switching databases.
  • Flexible Paradigms: Supports procedural, object-oriented and functional programming styles — use whichever fits your problem best.
  • Free & Open Source: No licensing fees, no commercial lock-in. Freely available under the Artistic License or GNU GPL.
  • Strong Unicode Support: Perl handles internationalization and multi-language text processing with comprehensive Unicode support built into the core.
  • Embedded in Many Systems: Many Linux distributions, web servers (via CGI), network devices and enterprise tools already have Perl built in — zero installation required.
  • Excellent Legacy Codebase Support: Billions of lines of production Perl exist. Knowing Perl is essential for maintaining and extending these systems.

✗ Disadvantages

  • Steep Learning Curve for Beginners: Perl’s flexible syntax (“There Is More Than One Way To Do It”) can be overwhelming for beginners who need clear, prescriptive guidance.
  • Write-Only Reputation: Perl is sometimes called a “write-only” language — code written by one developer can be extremely difficult for another to read, especially if cryptic idioms are used.
  • Declining Popularity: Python has largely displaced Perl in new projects for general scripting, web development and data science, leading to a shrinking job market for Perl-only roles.
  • Object-Oriented Model is Complex: Perl’s OOP system using bless, packages and manual inheritance is more complex and less intuitive than Python’s or Java’s class systems.
  • Less Modern Tooling: IDE support, linters, debuggers and modern development tools for Perl lag significantly behind Python, JavaScript and other contemporary languages.
  • Error Messages Can Be Cryptic: Without use strict and use warnings, Perl’s error messages can be vague and difficult to interpret for debugging.
  • No Built-In Async: Perl lacks modern async/await or native non-blocking I/O capabilities that are standard in languages like JavaScript (Node.js) or Python (asyncio).
  • Web Framework Ecosystem is Limited: While Dancer2 and Mojolicious exist, Perl’s web framework ecosystem is far less vibrant than Python’s (Django, Flask) or JavaScript’s (Express, Next.js).
  • Sigil Complexity: The three sigils ($, @, %) and context sensitivity (scalar vs. list context) add cognitive overhead compared to languages with simpler variable systems.
  • Perl 5 vs. Raku Confusion: The split between Perl 5 and Raku (formerly Perl 6) created confusion about the language’s future direction and fragmented the community.

📊 Perl vs. Other Languages: Quick Comparison

Feature Perl 5 Python 3 Ruby Bash
Text Processing⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Web Scraping⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Database Integration⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
System Automation⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Beginner Friendliness⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Module Ecosystem⭐⭐⭐⭐⭐ (CPAN)⭐⭐⭐⭐⭐ (PyPI)⭐⭐⭐⭐ (Gems)⭐⭐
OOP Support⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Regex Power⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

🎓 Conclusion

You have just completed the most comprehensive Perl programming guide available — covering everything from installation on every platform to real-world projects including a CRUD application, log parser, web scraper, API client and end-to-end data processing pipeline.

Perl remains a powerful, battle-proven language with an unmatched ecosystem for text processing, automation, system administration and data engineering. While it may have lost ground to Python in general scripting, its deep strengths in regex, CPAN, DBI and cross-platform portability make it indispensable in the right contexts.

Instructor: Mustafa Developer  |  “Ma