Perl Complete Cheat Sheet

Quick Reference Guide for Perl Programming

Your one-stop Perl reference for rapid development

Table of Contents

  1. Basics
  2. Variables
  3. Operators
  4. Control Structures
  5. Arrays
  6. Hashes
  7. Subroutines
  8. Regular Expressions
  9. File I/O
  10. String Manipulation
  11. References
  12. Packages and Modules
  13. OOP (Object-Oriented)
  14. Command-Line
  15. Common Patterns

1. Basics

Hello World

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

print "Hello, World!\
";

# Comments start with #

# Multi-line comment (POD format)
=begin comment
This is a multi-line comment
Second line
=end comment
=cut

Script Structure

#!/usr/bin/perl
use strict;          # Enforce variable declarations
use warnings;        # Enable warnings
use 5.010;          # Require Perl 5.10 or higher

# Main code here
print "Script running\
";

__END__
# Anything after __END__ is ignored

Running Perl

# Run script
perl script.pl

# Run one-liner
perl -e 'print "Hello\
"'

# Check syntax
perl -c script.pl

# Enable warnings
perl -w script.pl

# Use modules
perl -MPOSIX -e 'print strftime("%Y-%m-%d", localtime)'

2. Variables

Scalar Variables ($)

# Numbers
my $integer = 42;
my $float = 3.14159;
my $scientific = 1.23e-4;
my $hex = 0xFF;        # 255
my $octal = 0377;      # 255
my $binary = 0b11111111;  # 255

# Strings
my $string = "Hello";
my $single = 'World';  # No interpolation
my $multiline = "Line 1
Line 2
Line 3";

# String interpolation
my $name = "Alice";
my $greeting = "Hello, $name!";  # "Hello, Alice!"
my $literal = 'Hello, $name!';   # "Hello, $name!" (no interpolation)

# Special variables
$_ = "default variable";  # Default for many operations
$0  # Script name
$!  # Error message
$/  # Input record separator
$\  # Output record separator

Array Variables (@)

# Array declaration
my @array = (1, 2, 3, 4, 5);
my @empty = ();
my @mixed = (1, "two", 3.0, 'four');

# Array access
my $first = $array[0];     # 1
my $last = $array[-1];     # 5 (negative index from end)

# Array size
my $size = @array;         # 5 (scalar context)
my $last_index = $#array;  # 4 (last index)

# Array slice
my @slice = @array[1..3];  # (2, 3, 4)

# Range operator
my @range = (1..10);       # (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
my @letters = ('a'..'z');  # All lowercase letters

Hash Variables (%)

# Hash declaration
my %hash = (
  'name' => 'Alice',
  'age'  => 30,
  'city' => 'NYC'
);

# Alternative syntax (fat comma)
my %person = (
  name => 'Bob',     # Quotes optional for barewords
  age  => 25,
  city => 'LA'
);

# Hash access
my $name = $hash{'name'};     # 'Alice'
my $age = $hash{age};         # 30 (quotes optional)

# Check existence
if (exists $hash{name}) {
  print "Name exists\
";
}

# Delete key
delete $hash{city};

# Get all keys/values
my @keys = keys %hash;        # ('name', 'age')
my @values = values %hash;    # ('Alice', 30)

# Iterate
while (my ($key, $value) = each %hash) {
  print "$key => $value\
";
}

3. Operators

Arithmetic

$a + $b      # Addition
$a - $b      # Subtraction
$a * $b      # Multiplication
$a / $b      # Division
$a % $b      # Modulo
$a ** $b     # Exponentiation

$a++;        # Post-increment
++$a;        # Pre-increment
$a--;        # Decrement

String

$a . $b      # Concatenation: "Hello" . "World" = "HelloWorld"
$a x $b      # Repetition: "X" x 5 = "XXXXX"
$a eq $b     # String equality
$a ne $b     # String inequality
$a lt $b     # Less than
$a gt $b     # Greater than
$a le $b     # Less than or equal
$a ge $b     # Greater than or equal

Logical

$a && $b     # Logical AND
$a || $b     # Logical OR
!$a          # Logical NOT
$a and $b    # Low precedence AND
$a or $b     # Low precedence OR
not $a       # Low precedence NOT

$a // $b     # Defined-or (returns $b if $a undefined)

Comparison

# Numeric
$a == $b     # Equal
$a != $b     # Not equal
$a < $b      # Less than
$a > $b      # Greater than
$a <= $b     # Less than or equal
$a >= $b     # Greater than or equal
$a <=> $b    # Spaceship (returns -1, 0, or 1)

# String
$a eq $b     # Equal
$a ne $b     # Not equal
$a lt $b     # Less than
$a gt $b     # Greater than
$a cmp $b    # Spaceship for strings

Bitwise

$a & $b      # Bitwise AND
$a | $b      # Bitwise OR
$a ^ $b      # Bitwise XOR
~$a          # Bitwise NOT
$a << $b     # Left shift
$a >> $b     # Right shift

4. Control Structures

If-Elsif-Else

if ($condition) {
  # Code
} elsif ($other_condition) {
  # Code
} else {
  # Code
}

# Postfix if
print "Positive\
" if $num > 0;

# Unless (opposite of if)
unless ($error) {
  print "No error\
";
}

print "OK\
" unless $error;

# Ternary operator
my $result = ($condition) ? $true_val : $false_val;

Loops

# While loop
while ($count < 10) {
  print "$count\
";
  $count++;
}

# Until loop (opposite of while)
until ($done) {
  # Process
}

# For loop (C-style)
for (my $i = 0; $i < 10; $i++) {
  print "$i\
";
}

# Foreach loop
foreach my $item (@array) {
  print "$item\
";
}

# Foreach with index
for my $i (0 .. $#array) {
  print "array[$i] = $array[$i]\
";
}

# Hash iteration
foreach my $key (keys %hash) {
  print "$key => $hash{$key}\
";
}

# Postfix while
print "$_\
" while <FILE>;

# Loop control
next;        # Skip to next iteration (like 'continue')
last;        # Exit loop (like 'break')
redo;        # Restart current iteration

Switch (given/when)

use feature 'switch';

given ($value) {
  when (1)      { print "One\
"; }
  when ([2,3])  { print "Two or Three\
"; }
  when (/^abc/) { print "Starts with abc\
"; }
  default       { print "Something else\
"; }
}

5. Arrays

Array Operations

my @arr = (1, 2, 3, 4, 5);

# Add elements
push @arr, 6;           # Add to end: (1,2,3,4,5,6)
unshift @arr, 0;        # Add to beginning: (0,1,2,3,4,5,6)

# Remove elements
my $last = pop @arr;    # Remove from end: 6
my $first = shift @arr; # Remove from beginning: 0

# Slice
my @slice = @arr[1..3]; # Elements 1,2,3

# Splice (insert/remove)
splice @arr, 2, 0, 99;  # Insert 99 at index 2
splice @arr, 1, 2;      # Remove 2 elements starting at index 1

# Join array into string
my $str = join(",", @arr);  # "1,2,3,4,5"

# Split string into array
my @parts = split(/,/, "a,b,c,d");  # ('a','b','c','d')

# Sort
my @sorted = sort @arr;              # Alphabetic sort
my @numeric = sort { $a <=> $b } @arr;  # Numeric sort
my @reverse = sort { $b <=> $a } @arr;  # Reverse numeric

# Reverse
my @reversed = reverse @arr;

# Grep (filter)
my @evens = grep { $_ % 2 == 0 } @arr;

# Map (transform)
my @doubled = map { $_ * 2 } @arr;
my @strings = map { "Item: $_" } @arr;

# Unique (remove duplicates)
my %seen;
my @unique = grep { !$seen{$_}++ } @arr;

6. Hashes

Hash Operations

my %hash = (
  name => 'Alice',
  age  => 30,
  city => 'NYC'
);

# Access
my $name = $hash{name};

# Add/Update
$hash{country} = 'USA';
$hash{age} = 31;

# Delete
delete $hash{city};

# Check existence
if (exists $hash{name}) {
  print "Name exists\
";
}

# Check defined
if (defined $hash{name}) {
  print "Name is defined\
";
}

# Get keys, values
my @keys = keys %hash;
my @values = values %hash;
my @pairs = %hash;  # Flattened list

# Iterate
while (my ($k, $v) = each %hash) {
  print "$k => $v\
";
}

foreach my $key (keys %hash) {
  print "$key => $hash{$key}\
";
}

# Sort hash by key
foreach my $key (sort keys %hash) {
  print "$key => $hash{$key}\
";
}

# Sort hash by value
foreach my $key (sort { $hash{$a} <=> $hash{$b} } keys %hash) {
  print "$key => $hash{$key}\
";
}

# Hash slice
my @values = @hash{'name', 'age'};  # ('Alice', 30)

# Hash of hashes
my %database = (
  user1 => { name => 'Alice', age => 30 },
  user2 => { name => 'Bob', age => 25 }
);

my $alice_age = $database{user1}{age};  # 30

7. Subroutines

Function Definition

# Basic subroutine
sub hello {
  print "Hello, World!\
";
}

hello();  # Call

# With parameters
sub greet {
  my ($name) = @_;  # @_ contains all arguments
  print "Hello, $name!\
";
}

greet("Alice");

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

my $sum = add(5, 3);  # 8

# Default parameters (Perl 5.10+)
sub greet_with_default {
  my $name = shift // "Guest";  # Default to "Guest" if undefined
  print "Hello, $name!\
";
}

# Return values
sub get_values {
  return (1, 2, 3);  # Return list
}

my ($x, $y, $z) = get_values();

# Named parameters (using hash)
sub create_user {
  my %args = @_;
  print "Name: $args{name}, Age: $args{age}\
";
}

create_user(name => 'Alice', age => 30);

# Prototype (specify expected arguments)
sub add_numbers ($$) {  # Expects 2 scalars
  my ($a, $b) = @_;
  return $a + $b;
}

8. Regular Expressions

Pattern Matching

my $string = "Hello World 123";

# Match operator (=~)
if ($string =~ /World/) {
  print "Found 'World'\
";
}

# Not match (!~)
if ($string !~ /xyz/) {
  print "'xyz' not found\
";
}

# Case-insensitive
if ($string =~ /hello/i) {
  print "Match (case-insensitive)\
";
}

# Capture groups
if ($string =~ /(\w+)\s+(\w+)\s+(\d+)/) {
  print "Word1: $1\
";    # Hello
  print "Word2: $2\
";    # World
  print "Number: $3\
";   # 123
}

# Named captures (Perl 5.10+)
if ($string =~ /(?<word1>\w+)\s+(?<word2>\w+)/) {
  print "First: $+{word1}\
";
  print "Second: $+{word2}\
";
}

Substitution

my $text = "Hello World";

# Substitute (s///)
$text =~ s/World/Perl/;     # "Hello Perl"

# Global substitution
$text =~ s/l/L/g;           # "HeLLo PerL" (all 'l' to 'L')

# Case-insensitive
$text =~ s/hello/Hi/i;      # "Hi Perl"

# Delete pattern
$text =~ s/World//;         # "Hello "

# Transliteration (tr///)
$text =~ tr/a-z/A-Z/;       # Uppercase
$text =~ tr/aeiou/AEIOU/;   # Uppercase vowels only

# Delete characters
$text =~ tr/0-9//d;         # Delete all digits

Regular Expression Patterns

# Anchors
^       # Start of string
$       # End of string
\b      # Word boundary
\B      # Not word boundary

# Character classes
.       # Any character except newline
\d      # Digit [0-9]
\D      # Not digit
\w      # Word char [a-zA-Z0-9_]
\W      # Not word char
\s      # Whitespace [ \	\
\r\f]
\S      # Not whitespace

# Quantifiers
*       # 0 or more
+       # 1 or more
?       # 0 or 1
{n}     # Exactly n
{n,}    # n or more
{n,m}   # Between n and m

# Examples
/\d{3}/           # Exactly 3 digits
/\w+/             # One or more word chars
/colou?r/         # 'color' or 'colour'
/\d{2,4}/         # 2 to 4 digits
/^https?:\/\//    # http:// or https://

# Greedy vs Non-greedy
/<.*>/     # Greedy: matches longest
/<.*?>/    # Non-greedy: matches shortest

# Alternation
/cat|dog/          # 'cat' OR 'dog'
/(Mr|Mrs|Ms)\./    # Mr. or Mrs. or Ms.

# Groups
/(abc)+/           # Capturing group
/(?:abc)+/         # Non-capturing group

9. File I/O

Reading Files

# Open for reading
open(my $fh, '<', 'input.txt') or die "Cannot open: $!";

# Read line by line
while (my $line = <$fh>) {
  chomp $line;  # Remove newline
  print "$line\
";
}

close($fh);

# Slurp entire file
open(my $fh, '<', 'file.txt') or die $!;
my @lines = <$fh>;  # Array of lines
close($fh);

# Slurp into scalar
local $/ = undef;   # Undefine input separator
my $content = <$fh>;

# One-liner slurp
my $content = do { local(@ARGV, $/) = 'file.txt'; <> };

Writing Files

# Open for writing (overwrites)
open(my $fh, '>', 'output.txt') or die $!;
print $fh "Line 1\
";
print $fh "Line 2\
";
close($fh);

# Append mode
open(my $fh, '>>', 'output.txt') or die $!;
print $fh "Appended line\
";
close($fh);

# Write array
my @lines = ("Line 1\
", "Line 2\
");
open(my $fh, '>', 'file.txt') or die $!;
print $fh @lines;
close($fh);

File Tests

# File existence and properties
-e $file     # Exists
-f $file     # Regular file
-d $file     # Directory
-r $file     # Readable
-w $file     # Writable
-x $file     # Executable
-z $file     # Zero size
-s $file     # Size in bytes

# Example
if (-e "file.txt") {
  print "File exists\
";
  print "Size: ", -s "file.txt", " bytes\
";
}

if (-d "mydir") {
  print "Is a directory\
";
}

Directory Operations

# Open directory
opendir(my $dh, '.') or die $!;
my @files = readdir($dh);
closedir($dh);

# Filter out . and ..
@files = grep { !/^\.\.?$/ } @files;

# Glob (wildcard)
my @txt_files = glob("*.txt");
my @all_files = <*>;  # Same as glob("*")

# Create directory
mkdir("newdir") or die $!;

# Remove directory
rmdir("olddir") or die $!;

# Change directory
chdir("/tmp") or die $!;

10. String Manipulation

String Functions

my $str = "  Hello World  ";

# Length
my $len = length($str);  # 15

# Substring
my $sub = substr($str, 2, 5);  # "Hello"
substr($str, 0, 2) = "XX";     # Modify in place

# Upper/Lower case
my $upper = uc($str);    # "  HELLO WORLD  "
my $lower = lc($str);    # "  hello world  "
my $ucfirst = ucfirst($str);  # "  Hello world  "
my $lcfirst = lcfirst($str);  # "  hello World  "

# Trim whitespace
$str =~ s/^\s+//;        # Remove leading
$str =~ s/\s+$//;        # Remove trailing
$str =~ s/^\s+|\s+$//g;  # Remove both

# Split
my @words = split(/\s+/, "Hello World Perl");  # ('Hello','World','Perl')
my @parts = split(/,/, "a,b,c");               # ('a','b','c')

# Join
my $joined = join("-", @words);  # "Hello-World-Perl"

# Reverse
my $reversed = reverse($str);    # Reverse string
my @rev_array = reverse(@array); # Reverse array

# Chomp (remove trailing newline)
chomp($str);

# Chop (remove last character)
chop($str);

# Index (find substring)
my $pos = index($str, "World");   # Position of "World"
my $rpos = rindex($str, "o");     # Last occurrence

# Replace
$str =~ s/old/new/;      # Replace first
$str =~ s/old/new/g;     # Replace all

String Formatting

# sprintf (formatted string)
my $formatted = sprintf("Name: %s, Age: %d", $name, $age);
my $hex = sprintf("0x%04X", 255);  # "0x00FF"
my $float = sprintf("%.2f", 3.14159);  # "3.14"

# printf (print formatted)
printf("Value: %d\
", $value);

# Format specifiers
%s    # String
%d    # Decimal integer
%f    # Floating point
%x    # Hex (lowercase)
%X    # Hex (uppercase)
%o    # Octal
%b    # Binary
%e    # Scientific notation
%%    # Literal %

# Width and precision
%5d       # Min width 5
%05d      # Pad with zeros
%.2f      # 2 decimal places
%10.2f    # Width 10, 2 decimals
%-10s     # Left-align, width 10

11. References

Creating References

# Scalar reference
my $var = 42;
my $ref = \$var;    # Reference to scalar
print $$ref;        # Dereference: 42

# Array reference
my @array = (1, 2, 3);
my $aref = \@array;
print $aref->[0];   # 1
print @$aref;       # Dereference entire array

# Hash reference
my %hash = (a => 1, b => 2);
my $href = \%hash;
print $href->{a};   # 1
print %$href;       # Dereference entire hash

# Anonymous array
my $aref = [1, 2, 3];           # Creates array reference
print $aref->[0];               # 1

# Anonymous hash
my $href = {name => 'Alice', age => 30};
print $href->{name};            # 'Alice'

# Anonymous subroutine
my $sub_ref = sub { print "Hello\
"; };
$sub_ref->();                   # Call

Complex Data Structures

# Array of arrays
my @matrix = (
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
);

print $matrix[1][2];  # 6

# Array of hashes
my @users = (
  {name => 'Alice', age => 30},
  {name => 'Bob', age => 25}
);

print $users[0]{name};  # 'Alice'

# Hash of arrays
my %data = (
  fruits => ['apple', 'banana', 'orange'],
  colors => ['red', 'blue', 'green']
);

print $data{fruits}[0];  # 'apple'

# Hash of hashes
my %database = (
  user1 => {name => 'Alice', age => 30},
  user2 => {name => 'Bob', age => 25}
);

print $database{user1}{name};  # 'Alice'

12. Packages and Modules

Package Definition

# File: MyModule.pm
package MyModule;

use strict;
use warnings;
use Exporter 'import';

our @EXPORT_OK = qw(func1 func2 $var1);  # Export list
our @EXPORT = qw(func1);                  # Auto-export

our $VERSION = '1.00';

sub func1 {
  print "Function 1\
";
}

sub func2 {
  my ($arg) = @_;
  return $arg * 2;
}

1;  # Must return true

# Usage
# File: script.pl
use MyModule;           # Import @EXPORT
use MyModule qw(func2); # Import specific

func1();
my $result = func2(10);

Common Modules

# File handling
use File::Basename;
my $filename = basename("/path/to/file.txt");  # "file.txt"
my $dirname = dirname("/path/to/file.txt");    # "/path/to"

use File::Path qw(make_path remove_tree);
make_path("/tmp/a/b/c");     # Create nested dirs
remove_tree("/tmp/a");       # Remove tree

# Data structures
use Data::Dumper;
print Dumper(\%hash);        # Pretty-print data structure

# Time/Date
use POSIX qw(strftime);
my $date = strftime("%Y-%m-%d", localtime);

# JSON
use JSON;
my $json_text = encode_json(\%hash);
my $perl_data = decode_json($json_text);

# Command-line parsing
use Getopt::Long;
my $verbose;
my $output = "default.txt";
GetOptions(
  'verbose' => \$verbose,
  'output=s' => \$output
);

13. Object-Oriented Perl

Class Definition (Classic)

package Person;

use strict;
use warnings;

# Constructor
sub new {
  my ($class, %args) = @_;
  my $self = {
    name => $args{name} // "Unknown",
    age  => $args{age} // 0
  };
  bless $self, $class;
  return $self;
}

# Getter/Setter
sub name {
  my ($self, $value) = @_;
  $self->{name} = $value if defined $value;
  return $self->{name};
}

sub age {
  my ($self, $value) = @_;
  $self->{age} = $value if defined $value;
  return $self->{age};
}

# Method
sub greet {
  my ($self) = @_;
  print "Hello, I'm $self->{name}\
";
}

1;

# Usage
use Person;
my $person = Person->new(name => 'Alice', age => 30);
print $person->name();  # Alice
$person->age(31);
$person->greet();

Inheritance

package Employee;
use strict;
use warnings;
use parent 'Person';  # Inherit from Person

sub new {
  my ($class, %args) = @_;
  my $self = $class->SUPER::new(%args);  # Call parent constructor
  $self->{employee_id} = $args{id};
  return $self;
}

sub work {
  my ($self) = @_;
  print "$self->{name} is working\
";
}

1;

Modern OOP (Moose)

package Person;
use Moose;

has 'name' => (is => 'rw', isa => 'Str', default => 'Unknown');
has 'age'  => (is => 'rw', isa => 'Int', default => 0);

sub greet {
  my ($self) = @_;
  print "Hello, I'm " . $self->name . "\
";
}

__PACKAGE__->meta->make_immutable;
1;

# Usage
my $person = Person->new(name => 'Alice', age => 30);
$person->name('Bob');
print $person->age();

14. Command-Line Processing

ARGV and Command-Line

# @ARGV contains command-line arguments
# script.pl arg1 arg2 arg3

my $arg1 = $ARGV[0];
my $arg2 = $ARGV[1];

# Process all arguments
foreach my $arg (@ARGV) {
  print "Argument: $arg\
";
}

# Shift from @ARGV
my $first = shift @ARGV;

# Diamond operator (reads from files in @ARGV or STDIN)
while (<>) {
  print "Line: $_";
}
# Usage: perl script.pl file1.txt file2.txt

Getopt::Long

use Getopt::Long;

my $verbose = 0;
my $output = "output.txt";
my $count = 1;
my @libs;

GetOptions(
  'verbose'   => \$verbose,        # --verbose (flag)
  'output=s'  => \$output,         # --output filename
  'count=i'   => \$count,          # --count 10
  'lib=s@'    => \@libs            # --lib foo --lib bar
) or die "Error in command line arguments\
";

print "Verbose: $verbose\
";
print "Output: $output\
";
print "Count: $count\
";
print "Libs: @libs\
";

# Usage:
# perl script.pl --verbose --output result.txt --count 5 --lib a --lib b

15. Common Patterns

15.1 File Processing

# Read and process file
open(my $fh, '<', 'data.txt') or die $!;
while (my $line = <$fh>) {
  chomp $line;
  next if $line =~ /^#/;      # Skip comments
  next if $line =~ /^\s*$/;   # Skip blank lines
  
  # Process line
  my @fields = split(/,/, $line);
  print "Field 0: $fields[0]\
";
}
close($fh);

# One-liner file processing
perl -ne 'print if /pattern/' file.txt          # Grep
perl -pe 's/old/new/g' file.txt                 # Sed
perl -i.bak -pe 's/old/new/g' file.txt          # In-place edit

15.2 CSV Processing

# Simple CSV reader
open(my $fh, '<', 'data.csv') or die $!;
while (my $line = <$fh>) {
  chomp $line;
  my @fields = split(/,/, $line);
  print "Name: $fields[0], Age: $fields[1]\
";
}
close($fh);

# Using Text::CSV module
use Text::CSV;
my $csv = Text::CSV->new({ binary => 1 });

open(my $fh, '<', 'data.csv') or die $!;
while (my $row = $csv->getline($fh)) {
  my ($name, $age, $city) = @$row;
  print "Name: $name\
";
}
close($fh);

15.3 Hash Manipulation

# Count occurrences
my @items = qw(apple banana apple orange banana apple);
my %count;
$count{$_}++ for @items;
# %count = (apple => 3, banana => 2, orange => 1)

# Invert hash
my %original = (a => 1, b => 2, c => 3);
my %inverted = reverse %original;
# %inverted = (1 => 'a', 2 => 'b', 3 => 'c')

# Merge hashes
my %hash1 = (a => 1, b => 2);
my %hash2 = (c => 3, d => 4);
my %merged = (%hash1, %hash2);

# Hash slice assignment
@hash{qw(name age city)} = ('Alice', 30, 'NYC');
# Same as: $hash{name}='Alice', $hash{age}=30, $hash{city}='NYC'

15.4 List Processing

my @numbers = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

# Sum
my $sum = 0;
$sum += $_ for @numbers;

# Or use List::Util
use List::Util qw(sum max min);
my $total = sum @numbers;        # 55
my $maximum = max @numbers;      # 10
my $minimum = min @numbers;      # 1

# Filter even numbers
my @evens = grep { $_ % 2 == 0 } @numbers;

# Double all values
my @doubled = map { $_ * 2 } @numbers;

# Chain operations
my @result = map { $_ * 2 }      # Double
             grep { $_ % 2 == 0 } # Filter evens
             @numbers;
# @result = (4, 8, 12, 16, 20)

# Reduce
use List::Util qw(reduce);
my $product = reduce { $a * $b } @numbers;  # 3628800

15.5 Error Handling

# Die (throw exception)
die "Error message" if $error;
open(my $fh, '<', 'file.txt') or die "Cannot open: $!";

# Warn (print warning, continue)
warn "Warning: unusual value" if $value < 0;

# Eval (try-catch)
eval {
  # Code that might die
  open(my $fh, '<', 'file.txt') or die $!;
  # Process file
};

if ($@) {
  print "Error caught: $@\
";
}

# Try::Tiny (modern error handling)
use Try::Tiny;

try {
  # Risky code
  die "Something went wrong";
} catch {
  print "Caught error: $_\
";
} finally {
  print "This always runs\
";
};

15.6 Text Processing One-Liners

# Print lines matching pattern
perl -ne 'print if /pattern/' file.txt

# Print lines NOT matching
perl -ne 'print unless /pattern/' file.txt

# Substitute and print
perl -pe 's/old/new/g' file.txt

# In-place edit (backup to .bak)
perl -i.bak -pe 's/old/new/g' file.txt

# Sum numbers in file
perl -ne '$sum += $_; END { print $sum }' numbers.txt

# Count lines
perl -lne 'END { print $. }' file.txt

# Extract fields (like awk)
perl -F, -ane 'print $F[0]' file.csv    # Print first field

# Replace in multiple files
perl -i -pe 's/foo/bar/g' *.txt

# Print with line numbers
perl -ne 'print "$. : $_"' file.txt

# Uppercase all text
perl -pe '$_ = uc $_' file.txt

15.7 Hash Table Patterns

# Frequency counter
my @words = qw(apple banana apple orange banana apple);
my %freq;
$freq{$_}++ for @words;

foreach my $word (sort keys %freq) {
  print "$word: $freq{$word}\
";
}

# Group by criteria
my %groups;
foreach my $item (@items) {
  my $key = get_group($item);
  push @{$groups{$key}}, $item;
}

# Lookup table
my %color_code = (
  red   => '#FF0000',
  green => '#00FF00',
  blue  => '#0000FF'
);

my $code = $color_code{$color} // '#000000';  # Default black

# Cache/Memoization
my %cache;
sub expensive_function {
  my ($arg) = @_;
  return $cache{$arg} if exists $cache{$arg};
  
  # Calculate result
  my $result = complex_calculation($arg);
  $cache{$arg} = $result;
  return $result;
}

Quick Reference Tables

Variable Sigils

SigilTypeExampleAccess
$Scalar$name = “Alice”$name
@Array@arr = (1,2,3)$arr[0]
%Hash%hash = (a=>1)$hash{a}
&Subroutine&func or func()func()
*Typeglob*foo

Context

ContextMeaningExample
ScalarSingle value$x = @array (size)
ListMultiple values@x = @array (copy)
VoidNo return valueprint @array

Special Variables

VariableMeaning
$_Default variable
@_Subroutine arguments
$0Script name
$!Error message (errno)
$@Eval error
$?Child process exit status
$$Process ID
$.Current line number
$/Input record separator
$\Output record separator
$,Output field separator
@ARGVCommand-line arguments
%ENVEnvironment variables

File Test Operators

OperatorMeaning
-eExists
-fRegular file
-dDirectory
-lSymbolic link
-rReadable
-wWritable
-xExecutable
-zZero size
-sSize in bytes
-MModification age (days)
-AAccess age (days)
-CInode change age (days)

Perl for Hardware Engineers

Log File Parsing

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

# Parse simulation log
open(my $fh, '<', 'simulation.log') or die $!;

my $errors = 0;
my $warnings = 0;
my %test_results;

while (my $line = <$fh>) {
  chomp $line;
  
  # Count errors
  $errors++ if $line =~ /ERROR/;
  
  # Count warnings
  $warnings++ if $line =~ /WARNING/;
  
  # Extract test results
  if ($line =~ /TEST:\s+(\w+)\s+:\s+(PASS|FAIL)/) {
    $test_results{$1} = $2;
  }
  
  # Extract data
  if ($line =~ /Data:\s+0x([0-9A-Fa-f]+)/) {
    my $hex_value = hex($1);  # Convert hex string to number
    print "Foun\
";
  }
}

close($fh);

# Summary
print "\
=== Summary ===\
";
print "Errors: $errors\
";
print "Warnings: $warnings\
";
print "Test Results:\
";
foreach my $test (sort keys %test_results) {
  print "  $test: $test_results{$test}\
";
}

VCD/Signal Processing

# Parse signal changes
my %signals;

while (<VCD_FILE>) {
  # Extract signal changes
  if (/^#(\d+)/) {
    my $time = $1;
    # Process time
  }
  
  if (/^([01xz])(\w+)/) {
    my ($value, $signal_id) = ($1, $2);
    $signals{$signal_id}{$time} = $value;
  }
}

# Find signal transitions
foreach my $sig_id (keys %signals) {
  my @times = sort {$a <=> $b} keys %{$signals{$sig_id}};
  foreach my $t (@times) {
    print "Signal $sig_id = $signals{$sig_id}{$t} at time $t\
";
  }
}

Testbench Generation

#!/usr/bin/perl
# Generate SystemVerilog testbench

my $module_name = "my_dut";
my @signals = (
  {name => 'clk', width => 1, dir => 'input'},
  {name => 'reset_n', width => 1, dir => 'input'},
  {name => 'data_in', width => 32, dir => 'input'},
  {name => 'data_out', width => 32, dir => 'output'}
);

# Generate header
print "module tb_$module_name;\
\
";

# Generate signals
foreach my $sig (@signals) {
  my $type = ($sig->{dir} eq 'input') ? 'logic' : 'wire';
  if ($sig->{width} > 1) {
    printf("  $type [%d:0] $sig->{name};\
", $sig->{width}-1);
  } else {
    print "  $type $sig->{name};\
";
  }
}

print "\
";

# Generate DUT instantiation
print "  $module_name dut(\
";
my @port_connections;
foreach my $sig (@signals) {
  push @port_connections, "    .$sig->{name}($sig->{name})";
}
print join(",\
", @port_connections);
print "\
  );\
\
";

# Generate clock
print "  initial begin\
";
print "    clk = 0;\
";
print "    forever #5 clk = ~clk;\
";
print "  end\
\
";

print "endmodule\
";

Summary – Perl in One Page

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

# VARIABLES
my $scalar = 42;           # Scalar
my @array = (1,2,3);       # Array
my %hash = (a=>1, b=>2);   # Hash

# OPERATORS
# Arithmetic: + - * / % **
# String: . (concat), x (repeat), eq ne lt gt
# Logical: && || ! and or not
# Numeric compare: == != < > <= >= <=>
# String compare: eq ne lt gt le ge cmp

# CONTROL
if ($x > 0) { } elsif ($x < 0) { } else { }
while ($i < 10) { $i++; }
for my $i (0..9) { }
foreach my $item (@array) { }

# ARRAYS
push @arr, $val;           # Add to end
my $val = pop @arr;        # Remove from end
unshift @arr, $val;        # Add to start
my $val = shift @arr;      # Remove from start
my @sorted = sort @arr;
my @filtered = grep { $_ > 5 } @arr;
my @mapped = map { $_ * 2 } @arr;

# HASHES
$hash{key} = $value;
my @keys = keys %hash;
my @values = values %hash;
exists $hash{key};
delete $hash{key};

# FUNCTIONS
sub func { my ($arg1, $arg2) = @_; return $result; }
my $ret = func($a, $b);

# REGEX
$str =~ /pattern/;         # Match
$str =~ s/old/new/g;       # Substitute
my @parts = split(/,/, $str);
my $joined = join("-", @parts);

# FILE I/O
open(my $fh, '<', 'file.txt') or die $!;
my @lines = <$fh>;
close($fh);

# REFERENCES
my $aref = \@array; print $aref->[0];
my $href = \%hash;  print $href->{key};
my $aref = [1,2,3]; # Anonymous array
my $href = {a=>1};  # Anonymous hash

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top