Perl Basics
Programs
Perl file has extension ".pl". Start file with "shebang":
#!/usr/bin/perl -w
On unix systems, this tells the compiler which binary to use and with what options.
End lines with semicolon. Comment with #. Example: "hello_world.pl"
#!/usr/bin/perl -w
# Here is a comment.
print "Hello World!"
Execute from command line with
perl hello_world.pl
Pragmas
use strict; # tells the compiler to be stricter in checking for problems
use integer; # all arithmetic uses integers only
List Literals
(2, 5, 8) # a list with three numerical elements
(1..10) # a list with ten numerical elements
($n+3, $m) # a list with two elements
("a", "b", "c") # a list with three string elements
qw( a b c ) # same list
Scalar Variables
Scalar variables are initialized as undef, which translates to 0 for numbers and ´´ for strings.
$age = 12;
$name = "Bill";
($name, $age) = ("Bill", 12);
Arrays and Lists
@dogs = ("Lassie", "Biff", "Bruno");
@ages = (3, 4, 5);
$Lassie_age = $ages[0];
$last_element_index = $#dogs # gives index of last element = size-1
$last_element = $dogs[$#dogs] # last element
$last_element = $dogs[-1] # also refers to last element
# shift, unshift, push, pop, reverse, sort
@array = qw$ a b c $; # qw operates on any punctuation pair
$first = shift @array; # $first is "a", @array becomes ("b", "c")
unshift @array, $first; # @array is back to ("a", "b", "c")
$last = pop @array; # $last is "c", @array becomes ("a", "b")
push @array, $last; # @array is back to ("a", "b", "c")
push @array, 1..3; # @array becomes ("a", "b", "c", 1, 2, 3)
@array = reverse @array; # @array becomes (3, 2, 1, "c", "b", "a")
@array = sort @array; # @array becomes (1, 2, 3, "a", "b", "c")
@array = reverse sort @array; # @array becomes ("c", "b", "a", 3, 2, 1)
# iterate over an array
foreach $element (@my_array){
# do something with $element
# the elements of @my_array can be altered this way
}
# scalar vs list context
@array = qw( a b c );
$number = @array; # $number is 3
$number = scalar @array; # more explicit
@array = "hi, there"; # becomes a list with one string element
Hash Variables
%list = ("Lassie", 3, "Biff", 4, "Bruno", 5);
%same_list = (
Lassie => 3,
Biff => 4,
Bruno => 5, # final trailing comma is legal but optional
); #strings implicitly quoted
$same_list_again{Lassie} = 3;
$same_list_again{Biff} = 4;
$same_list_again{Bruno} = 5;
$Lassie_age = $list{Lassie};
# extract keys and values
my @keys = keys %list; # @keys is ("Lassie", "Biff", "Bruno")
my @values = values %list; # @values is (3, 4, 5)
# check for a given key
if (exists $list{"Rover"}){...}
# delete a given key
delete $list{"Lassie"})
# iterate over a hash:
while ( ($key, $value) = each %my_hash ){
# do something with $key and $value
}
# iterate over a hash in key-sorted order
foreach $key (sort keys %hash) {
$value = $hash{$key};
# do something with $key and $value
}
# flip a hash (values must be unique)
%ip_addresses = reverse %host_names;
Variable Scope
Variables are global by default. Loop control variables are local to the loop. Use the "my" command to declare locally.
Strings
Use double quotes to allow variable interpolation.
$name = "Barney";
print 'My name is $name'; # prints My name is $name
print "My name is $name"; # prints My name is Barney
Concatenate with period
$temp = "another "."variable"; # temp is another variable
Substring
print substr $name, 2, 3; # returns ott
print substr $name, 2, 3, "at"; # returns ott
print $name; # returns Scat
my $suffix = substr($file, -3); # last 3 characters
String comparison
if ($name eq "Barney")... # equals
# also ne, gt, ge, lt, le
Tokenizer
use Text::ParseWords;
my @list = quotewords(":", 1, $line); # specific delimiter
OR
my @list = shellwords($line); # split by whitespace
Length
my $size = length($line)
Dates
Represented as seconds since Jan 1, 1970 using long integers.
Date::Parse - Parse date strings into time values
use Date::Parse;
$time = str2time($date);
Timestamp
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
printf "%4d-%02d-%02d %02d:%02d:%02d\n",$year+1900,$mon+1,$mday,$hour,$min,$sec;
gives
2007-07-19 15:33:29
Default and Special Variables
# scalar default variable is $_
foreach (1..10) { # Uses $_ by default
print "I can count to $_!\n";
}
# array default variable is @_
sub is_greater{
my ($first, $second) = @_;
return ($first > $second);
}
- $0 is the name of the called program
- $1 - $99 are regular expression capture variables
- @ARGV is the array of arguments from the command line (not including program name)
- $! is the error message given by the last failed command
- $| set this to 1 to turn off buffering for the current output filehandle
- $` is everything before a regular expression match
- $& is the regular expression match itself
- $' is everthing after the regular expression match
Conditionals and Loops
Perl interprets the value 0 as false for numbers. The strings and '0' are interpreted as false.
Compound
if (expression) {block}
else {block}
unless (expression) {block}
else {block}
if (expression) {block}
else {block}
if (expression1) {block}
elsif (expression2) {block}
else {block}
while (expression) {block}
until (expression) {block}
for ($i = 0; $i < $max; $i++) {block}
foreach var (list) {block}
One-liners
statement if expression;
statement unless expression;
statement while expression;
statement until expression;
System Calls
If you aren't collecting input from the call:
my $status = system("test -e $file");
If you are collecting input:
my @p_file_params = `$p_external_programs{pfprint} -f $p_file`
or die("pfprint failed!\nAre you sure \"$p_file\" is a valid P-file?\n", usage());
Errors and Warnings
die aborts the program and gives a non-zero exit status:
open(FH, $fileName) or die "open $fileName failed: $!";
# add a newline to the die argument to suppress line numbers
if (@ARGV != 2){
die "There should be two arguments!\n";
}
warn is just like die except that the program does not abort