Starting a new Perl project can be a time-consuming process, especially when setting up the basic structure and including commonly used modules and functions. To streamline this process, I've developed a comprehensive Perl template that serves as an excellent starting point for various projects. In this post, I'll share my template and break down its components, explaining how each part contributes to a solid foundation for Perl development.
x#!/usr/bin/env perl
# Import necessary modules and enable features
# Term::ANSIColor: For adding color to terminal output
# feature 'say': Provides a shorthand for 'print' with an automatic newline
# FindBin: Helps locate the directory where the script is running
# Data::Dumper: Useful for debugging complex data structures
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pragmas
use ;
use ;
use ;
use open qw(:std :utf8);
use :: qw(:constants);
use qw(say state);
use qw($RealBin);
use :: ;
# Configure Data::Dumper for better readability of debug output
# These settings affect how Data::Dumper will format its output
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Config
# Configure Data::Dumper
$Data:::: = 1; # Produce output that's valid as Perl code
$Data:::: = 1; # Turn on pretty-printing with a single-space indent
$Data:::: = 1; # Sort hash keys for consistent output
$Data:::: = 1; # Avoid outputting variable names (just the structure)
# Define main data structures used throughout the script
# $db: An empty hash reference, possibly for storing data (currently unused)
# $dt: A dispatch table mapping function names to their references
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Vars
my $db = {};
my $dt = {
=> \&typeWriter,
=> \&sleepyTime,
=> \&strScan,
};
# Enable autoflush to ensure immediate output (useful for interactive scripts)
$|++;
# Main execution block
# This is where the primary logic of the script would go
# Currently, it only calls the sleepyTime function with an argument of 3
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Init
# Code goes here!
$dt->{zzz}(3);
# Define utility functions used throughout the script
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Subs
# sleepyTime: Pauses execution for a random or fixed duration
# Parameters:
# $random: Maximum random sleep time
# $fixed: Fixed sleep time to add to the random time
sub
{
my $random = shift // 0;
my $fixed = shift // 0;
# Early return if both random and fixed times are too small
return 0 if ( $random <= 2 and $fixed == 0 );
# Calculate sleep time and display it
my $sleep = int( rand( $random ) ) + $fixed;
say |> |, | for |, $sleep, | ...|;
sleep $sleep;
}
# typeWriter: Prints text with a typewriter effect
# Parameters:
# $text: The string to be printed
sub
{
my $text = shift;
# Use regex to process each character of the text
$text =~ `.`
select(undef, undef, undef, rand(0.05)); # Small random delay
print $&; # Print the matched character
`sger;
}
# strScan: Creates a string scanner object with various utility methods
# Parameters:
# @_: The string to be scanned (joined if multiple arguments)
sub strScan
{
my $string = qq|@_|;
@_ = undef; # Clear @_ to free memory
# Initialize scanner position
my $pos = 0;
# Calculate end of string position
my $eos = length ( $string );
# Return a hash of closure functions for string manipulation
return
{
pos => sub { return $pos }, # Get current position
mod_pos => sub { $pos = shift }, # Modify current position
eos_check => sub { return $eos == $pos ? 0 : 1; }, # Check if not at end of string
find => sub # Find next occurrence of a regex pattern
{
my $regex = shift;
# Attempt to match the regex from the current position
if ( my ($found) = substr ( $string, $pos ) =~ m~($regex)~ )
{
# Calculate match details
my ( $start, $length ) = ( $-[0], length ( $found ) );
# Update scanner position
$pos += $start + $length;
# Return match information
return
{
pos => $pos,
match_start => $start,
match_length => $length,
match => $found,
}
}
else
{
# If no match, set position to end of string
$pos = $eos;
return undef;
}
}
}
}
# Mark the end of the executable code
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ End
__END__
# Example usage of the strScanner function
# This demonstrates how to use the strScan function to parse a string
# strScanner demo:
my $scan = strscan::create ( 'This is just a test!' );
say q|start position: |, $scan->{pos}(), qq|\n|; # Print initial position
# Iterate through the string, finding word characters
while ( $scan->{eos_check}() )
{
if ( my $match = $scan->{find}('\w+') )
{
say q|match: |, $match->{match};
say q|pos: |, $match->{pos};
say q||;
}
}
say q|end position: |, $scan->{pos}(); # Print final position
xxxxxxxxxx
#!/usr/bin/env perl
use ;
use ;
use ;
use open qw(:std :utf8);
use :: qw(:constants);
use qw(say state);
use qw($RealBin);
use :: ;
Let's break this down:
The shebang (#!/usr/bin/env perl
) ensures the script runs with the correct Perl interpreter.
strict
and warnings
are crucial pragmas that help catch common programming errors.
utf8
and open qw(:std :utf8)
enable proper UTF-8 handling for input/output.
Term::ANSIColor
allows for colorized terminal output.
feature qw(say state)
enables the say
function (print with newline) and state
variables.
FindBin
helps locate the directory where the script is running.
Data::Dumper
is invaluable for debugging complex data structures.
xxxxxxxxxx
$Data:::: = 1;
$Data:::: = 1;
$Data:::: = 1;
$Data:::: = 1;
These settings customize Data::Dumper's output:
Purity
: Ensures the output is valid Perl code.
Indent
: Enables pretty-printing with a single-space indent.
Sortkeys
: Sorts hash keys for consistent output.
Terse
: Avoids outputting variable names, showing just the structure.
xxxxxxxxxx
my $db = {};
my $dt = {
=> \&typeWriter,
=> \&sleepyTime,
=> \&strScan,
};
Here, we define two main data structures:
$db
: An empty hash reference, potentially for storing data (currently unused).
$dt
: A dispatch table that maps function names to their references. This allows for dynamic function calls.
xxxxxxxxxx
$|++;
This line enables autoflush, ensuring immediate output. It's particularly useful for interactive scripts or when you need real-time feedback.
xxxxxxxxxx
$dt->{zzz}(3);
This is where the main logic of your script goes. This template includes starter code that calls the sleepyTime
function with an argument of 3 using the dispatch table.
xxxxxxxxxx
sub
{
my $random = shift // 0;
my $fixed = shift // 0;
return 0 if ( $random <= 2 and $fixed == 0 );
my $sleep = int( rand( $random ) ) + $fixed;
say |> |, | for |, $sleep, | ...|;
sleep $sleep;
}
This function pauses execution for a random or fixed duration. It's useful for adding delays in scripts, perhaps to simulate human-like behavior or to prevent overwhelming a system with rapid requests.
xxxxxxxxxx
sub
{
my $text = shift;
$text =~ `.`
select(undef, undef, undef, rand(0.05));
print $&;
`sger;
}
typeWriter
prints text with a typewriter effect, adding a small random delay between each character. This can be used for creating more engaging command-line interfaces.
xxxxxxxxxx
sub
{
my $string = |@_|;
@_ = undef;
my $pos = 0;
my $eos = length ( $string );
return
{
pos => sub { return $pos },
=> sub { $pos = shift },
=> sub { return $eos == $pos ? 0 : 1; },
=> sub
{
my $regex = shift;
if ( my ($found) = substr ( $string, $pos ) =~ m~($regex)~ )
{
my ( $start, $length ) = ( $-[0], length ( $found ) );
$pos += $start + $length;
return
{
pos => $pos,
=> $start,
=> $length,
=> $found,
}
}
else
{
$pos = $eos;
return undef;
}
}
}
}
strScan
creates a string scanner object with various utility methods. This is a powerful tool for parsing and manipulating strings, offering methods to check position, find patterns, and more.
To use this template for your projects:
Save the template as a .pl
file (e.g., template.pl
).
Copy this file when starting a new project.
Modify the Init
section to include your project-specific code.
Add or remove modules as needed for your project.
Customize the utility functions or add new ones to suit your project's requirements.
Remember to update the $dt
dispatch table if you add new functions that you want to call dynamically.
This Perl template provides a robust foundation for new projects, offering a blend of essential pragmas, useful modules, and versatile utility functions. By using this template, you can:
Ensure consistent code quality with strict
and warnings
.
Handle UTF-8 encoding properly.
Easily debug with pre-configured Data::Dumper
.
Utilize handy functions for string manipulation, timing, and formatted output.
Save time on initial project setup and focus more on implementing your core functionality.
Whether you're working on a quick script or a larger application, this template can help jumpstart your Perl development process, providing a flexible and feature-rich starting point for various projects.