Perl basics for Rex
Rex, the friendly automation framework does not expect much previous programming or Perl experience, though knowing a few foundational elements may go a long way.
While we provide a Just enough Perl for Rex page on our website, I often find myself sharing my own experience about getting started with Perl.
I decided to write my own take about the basics from a Rex perspective, and collect further resources I keep recommending or referring to.
Let’s see what I considered useful when I started out.
Documentation
Finding relevant information provides a solid foundation for learning effectively.
Read documentation
Perl provides the perldoc
command to read documentation on the command line.
For example perldoc perldoc
shows its own documentation, and perldoc Rex
shows the documentation of Rex.
To browse Perl’s own documentation online, I recommend either the Perldoc Browser or MetaCPAN. The latter also renders the documentation of all CPAN modules too, including Rex.
Write documentation
Perl has extensive documentation in the Plain Old Documentation (POD) format, which describes itself as:
a simple-to-use markup language used for writing documentation for Perl, Perl programs, and Perl modules.
No need to feel discouraged by either “plain” or “old” in its name, though – POD proves simple enough to even write books in it.
As a Perl project, Rex transparently supports documenting custom solutions in the POD format, and also uses POD for its own documentation.
=pod
=head1 Heading
Ordinary paragraph with B<bold> and I<italic> text,
as well as with C<inline code> and L<hyperlink|https://www.example.com>.
Command paragraphs treat the text specially and starts with “=”,
like “=pod” above.
indent verbatim paragraphs
for example for code blocks
=cut
Modules
Modules group together related functionality to reuse elsewhere. See perlmod as a reference.
Core modules
Perl itself comes with a set of modules to reuse common functionality between
projects. Use the
corelist
command
to find more information about the core modules.
For example to list all core modules coming with perl-5.40.1, use corelist -v
5.40.1
on the command line.
Import them with the use
function:
use Time::Local; # import functionality from the Time::Local module
Other modules
The Comprehensive Perl Archive Network (CPAN) currently hosts the work from 14500+ authors in the form of 45000+ distributions containing 220000+ modules. Some of them likely solves the same problem one has to solve for their own use case.
The cpan client comes with Perl, while CPAN itself supports other clients too, like cpanm, and cpm.
Use the system package managers or one of those clients to install a distribution from CPAN locally, then reuse the modules:
use Rex; # imports the Rex module
Variables
Perl provides three built-in data types: scalars, arrays, and hashes.
See perldata as a reference.
I will use the values from the below examples throughout this post.
Naming
Perl calls the first character of a variable a sigil, denoting to the type of the data stored or accessed:
$
for scalars@
for arrays%
for hashes
The variable name itself must begin with a letter or an underscore, and then may contain letters, underscores, and digits.
Scalars
A scalar represents a single value, like a number, a string, or a reference to other variables and objects.
my $name = 'Rex'; # a string
my $year = 2025; # a number (integer)
my $pi = 3.14; # a number (float)
my $site = Site->new(); # an instance of a Site object
Arrays
An array represents an ordered list of scalars.
my @projects = ( 'Rex', 'Perl' ); # list of two scalars, in that order
my @quoted_projects = qw( Rex Perl ); # qw() quotes the words
Use the index of an element to access it, starting the numbering from 0. Negative numbers count from the end.
my $first_project = $projects[0]; # Rex; note the $ sigil to access a scalar
my $last_project = $projects[-1]; # Perl
Hashes
Hashes represent an unordered collection of key-value pairs.
my %site_for = (
rex => 'rexify.org', # the fat arrow autoquotes simple values on left
'perl' => 'perl.org', # recommended trailing comma
);
Access values by the name of their associated keys.
my $rex_site = $site_for{'rex'}; # rexify.org
my $perl_site = $site_for{perl}; # curly braces autoquote simple values too
References
A reference represents a scalar value that references something else: for example another scalar, an array, or a hash. Since arrays and hashes contain scalars, using references enable building complex data structures through nesting.
See perlref as a reference (pun intended 🙃), and perlreftut for “90% of the benefit with 10% of the details.”
Create references
Perl provides two main ways to create references:
my $ref_to_projects = \@projects; # use \ in front to make a reference
my $ref_to_site_for = \%site_for;
my $projects_ref = [ 'Rex', 'Perl' ]; # note the square brackets for arrayrefs
my $site_for_ref = {
rex => 'rexify.org', # note the curly brackets for hashrefs
perl => 'perl.org',
};
Use references
Accordingly, Perl provides two ways to use references too, called dereferencing:
# using curly braces
my @project = @{$projects_ref}; # dereference as an array
my %site_for = %{$site_for_ref}; # dereference as a hash
my $first_project = @{$projects_ref}[0];
my $perl_site = %{$site_for_ref}{perl};
# using an arrow
my $last_project = $projects_ref->[-1];
my $rex_site = $site_for_ref->{rex};
# postfix dereferencing with modern Perl
use v5.24; # use perl-5.24 features
my @project = $projects_ref->@*;
my %site_for = $site_for_ref->%*;
Dump data structures
Perl comes with the Data::Dumper core module to stringify data structures.
use Data::Dumper;
print Dumper \@projects; # Dumper dumps scalars, hence the reference
# prints this:
$VAR1 = [
'Rex',
'Perl'
];
I also recommend using Data::Printer from CPAN for an improved experience:
use Data::Printer; # or use DDP as an alias
p @projects; # recognizes the type of parameter on its own
# prints this:
[
[0] "Rex",
[1] "Perl",
]
Conditions
Make decisions based on comparing values.
Comparing strings
if ( $name eq 'Rex' ) { # condition to check; eq stands for equal
print 'Hi Rex!'; # branch to execute when true
}
if ( $name ne 'FErki' ) { # ne stands for not equal
print "Hi, $name!"; # double quotes interpolate $name, prints Hi Rex!
)
else { # optional branch to execute otherwise
print 'You must be FErki!';
}
Comparing numerical values
if ( $year == 2025 ) { # note the double = signs
print 'this year';
}
elsif { $year < 2025 ) { # further condition in case previous didn’t match
print 'in the past';
}
else { # optional branch to execute otherwise
print 'in the future';
}
Regular expressions
See perlre as a reference, and perlretut as a tutorial to get started. If you already know about regular expressions, see also perlrequick for a quick start.
Matching
print 'match' if $name =~ m/Rex/; # match due equivalence
print 'match' if $name =~ m/rex/; # does not match due to lowercase r
print 'match' if $name =~ m/rex/i; # match due to case insensitive matching
print 'match' if $name =~ qr{rex}i; # match, qr stands for quote like a regex
Loops
Iterate over data structures with a collection of values, like arrays and hashes.
foreach my $project (@projects) {
print $project; # prints RexPerl
}
foreach my $project ( keys %site_for ) { # no guarantees about ordering
my $site = $site_for{$project}; # $site gets set on each iteration
}
Loop control
Stop the loop or continue with the next element given a certain condition.
foreach my $project (@projects) {
print $project; # prints Rex
last if $project eq 'Rex'; # stop the loop when condition matches
}
foreach my $project (@projects) {
next if $project eq 'Rex'; # skip the rest of loop when condition matches
print $project; # prints Perl
}
Subroutines
Subroutines serve as user-defined functions.
sub greet_rex {
print 'Hi Rex!';
}
greet_rex(); # prints Hi Rex!
Pass parameters
sub greet_user {
my ($name) = @_;
print "Hi $name!";
}
greet_user('FErki'); # prints Hi FErki!
Return results
sub get_this_year {
return 2025;
}
my $current_year = get_this_year(); # 2025
Further resources
Due to Perl’s long history one may find a wide range of resources to learn from. I found the below ones valuable while I learned about Perl:
- Just enough Perl for Rex by us, the Rex project
- Minimum Viable Perl by kablamo
- Impatient Perl by Greg London
- Extreme Perl by Robert Nagler
- Modern Perl by chromatic