Index

Table of contents

perl

pragmas

enable more recent perl features
use 5.26.1;
enable warnings for file
use warnings;
enable warnings (verbose)
use diagnostics;
enable unicode support
use utf8;
automatically exit program on common problems (such as IO exceptions)
use autodie;
disable requirement to set scope on every variable
no strict "vars";

scalar

declaring a scalar
my $s = 'foo';
erasing a scalar
my $s = undef;
line number (set by certain flags)
$.
perl has only one scalar type for both string and number
my $n=3
my $s=abc
assign multiple variables in one line
($a, $b) = (1, 2);
use underscore for readability in large numbers
my $millis=3_600_000
floating point number definitions
my $a=1.5
my $b=1.5e9  #1.5*10^9
my $c=1.5E9  #1.5*10^9
my $d=1.5E-9 #1.5/10^9
hex number
my $h=0xFF   #255
my $p=0x1p10 #1*2^10=1024
basic math
10+20*30/4
modulus
5%4
power
10**3 #10^3=1000
generate random number 0-max
my $rand = rand [max];
incrementors
$a++;    # returns $i
$a--;    # returns $i
++$a;    # returns $i + 1
--$a;    # returns $i - 1
min max sum
use List::Util qw(min, max, sum);
$one = min(1, 2);
$two = max(1, 2);
$three = sum(1, 2);
compound assignment operators
$a += 1;
$a -= 1;
$a *= 2;
$a /= 2;
$a **= 2;
compare numbers
1 == 1
1 != 2
1 < 2
2 > 1
1 <= 2
2 >= 1
convert scalar to int
int('44.5')
convert non-scalar type into scalar
scalar @myarray
scalar %myhash
perls default variables
$_    # loop iterator
$$    # pid
$@    # last error message eval
$!    # last error message system
@_    # method arguments
$.    # last line number read from file

$n    # regex groups (n = 1-9)
$`    # also in ${^PREMATCH}  head:  input skipped before regex match occured
$&    # also in ${^MATCH}     match: input matching regex
$'    # also in ${^POSTMATCH} tail:  input remaining after regex match completed
%+    # regex named matches

text

compound assignment operators
$s .= 'a';
get length of string
my $length = length $s;
single quotes are literal strings and dont allow control characters such as \n
my $s='only escape single quote\' and backslage \\'
double quoted string with control characters and variables
my $s="\t a \n"
my $s="variable: $myvar"
my $s="variable: ${myvar}no space after variable"
case shifting
my $upper       = "\U$lower";
my $capitalized = "\u$lower";
my $lower       = "\L$upper";
my $inverse_cap = "\l$upper";
my $mixed       = "\U$lower\E$original\L$upper";
string concatenation
my $s="abc" . "def";
string repetition
my $dots='.' x 12;
hex string to number
hex('123456789ABCDEF')
hex('0x123456789ABCDEF')
oct string to number
oct('0123456780')
oct also accepts hex
oct('0x123456789ABCDEF')
compare strings
'a' eq 'a'
'a' ne 'b'
'a' lt 'b'
'b' gt 'a'
'a' le 'b'
'b' ge 'a'
remove a single \n from end of line (if present)
my $zero_or_one = chomp $myvar;
my $zero_or_one = chomp($myvar);
string to lower case
my $lower = lc($string);
string to upper case
my $upper = uc($string);
capitalize
my $capitalized = ucfirst($input);
escape regex meta characters
my $escaped = quotemeta($input);
get first index of substring
my $index = index($string, $sub);
my $index = index($string, $sub, $lower_bound);
example
my $index = index('0123456789', '456');
get last index of substring
$index = rindex($string, $sub);
$index = rindex($string, $sub, $upper_bound);
extracting a substring
my $sub = substr($string, $start);
my $sub = substr($string, $start, $length);
examples
say substr('0123456789', 4);
say substr('0123456789', -2);
say substr('1234', 0, 2);
inserting / replacing substring
substr($string, $start, $length, $replace);
substr($string, $start, $length) = $replace;
substr($string, $start, $length) =~ s/regex/replace/flags;
example: insert
my $insert = '01236789';
substr($insert, index($insert, '6789'), 0, "45");
say "$insert";
example: replace
my $modify = '0123ab6789';
substr($modify, index($modify, 'ab'), 2, "45");
say "$modify";
example: regex replace on substring only
my $modify = 'ignore change ignore';
substr($modify, index($modify, 'change'), length('change')) =~ s/$/d/;
say "$modify";
split $_ into columns
my @columns = split;
split name scalar into columns
my @result = split " ", $input;
print string and ident up to [n] characters
my $formatted = sprintf "%[n]s\n", [string];
print number and ident up to [n] characters
my $formatted = sprintf "%[n]d\n", [number];
print number with [n] decimals
my $formatted = sprintf "%.[n]f\n", [number];
documentation
https://perldoc.perl.org/functions/sprintf.html

arrays

define an empty array
@myarray = ();
define an array with values
@myarray = (1,2,3,4,5)
@myarray = (1..5)
@myarray = ('a', 'b', 'c', 'd', 'e')
@myarray = ('a', 1..5, 7, $myvar)
get array size
my $size = @myarray
if(scalar @myarray == 2) { ... }
get the last index in an array (size -1)
$#array
get the size of an array
$#array + 1
@array + 0
my $size = @array;
get the last element in an array
$array[$#array]
$array[-1]
for array [myarray] set index 0 to 'value' (creates array if necessary)
$myarray[0] = 'value';
composite assignment statements modify the array
$a[index] += 1;
$a[index] -= 1;
$a[index] *= 2;
$a[index] /= 2;
$a[index] **= 2;
add values to the beginning of an array
unshift @myarray, 1;
unshift @myarray, 'a';
unshift @myarray, 1..5;
unshift @myarray, $myvar;
unshift @myarray, @myotherarray;
add values to the end of an array
push @myarray, 1;
push @myarray, 'a';
push @myarray, 1..5;
push @myarray, $myvar;
push @myarray, @myotherarray;
remove first element in array
my $first = shift @myarray
remove last element in array
my $last = pop @myarray
remove all elements starting at index [i]
my @deleted = splice [i]
my @deleted = splice @myarray, [i]
remove [n] elements starting at index [i]
my @deleted = splice [i], [n]
my @deleted = splice @myarray, [i], [n]
insert array @insert at index [i]
my @deleted = splice [i], 0, @insert
my @deleted = splice @myarray, [i], 0, @insert
replace a part of an array
my @deleted = splice [i], [n], @insert
my @deleted = splice @myarray, [i], [n], @insert
extract a slice
my @slice = @array[0,5,7];
my @slice = (split)[1,-1];
filter array using grep
my @filtered = grep /\d+/, @array;
my @filtered = grep { /\d+/ } @array;
count matching items only
my $count = grep /\d+/, @array;
map function to transform list items
my @mapped = map $_ + 1, @array;
my @mapped = map {$_ + 1} @array;
filter and map
my @mapped = map $_ + 1, grep /\d+/, @array;
my @mapped = map {$_ + 1} grep {/\d+/} @array;
merge arrays a & b
@merge = (@a, @b)
@merge = (@a, @b, $scalar)
join array elements into a string
my $joined = join "|", @array ;
reverse elements (does not modify original array)
my @reversed = reverse @ordered

sorting

sort elements ascii / unicode order (does not modify original array)
my @sorted = sort @unsorted;
my @sorted = sort {$a cmp $b} @unsorted;
case insensitive sort
my @sorted = sort {"\U$a" cmp "\U$b"} @unsorted;
sort numerically
my @sorted = sort { $a <=> $b } @unsorted;

hashes

create empty hash
my %map = ();
put hash entry
$map{'d'} = 4;
put multiple entries
@map{ @keys } = @values;
@map{ ('a', 'b') } = (1,2);
create hash with entries
my %map = (
	'a' => 1,
	'b' => 2,
	'c' => 3,
);
get value from hash using key
$map{$key}
get values for multiple keys at once
@map{@keys}
get map size
my $size = %map;
delete key with its value
delete $map{'mykey'};
get keys as array
my @keys = keys %map;
get values as array
my @values = values %map;
get sub-hash for specified keys
my %sub = %map{ @keys }
my %sub = %map{ ('a', 'c') }
if not empty
if(%map) {
	say "hash is NOT empty";
} else {
	say "hash IS empty";
}
check if a key exists
if(exists $map{'mykey'}) {
	say "key exists";
} else {
	say "key does not exist";
}
iterate keys
foreach(keys %map) {
	say "key $_";
}
iterate keys and values
foreach(keys %map) {
	say "key $_ value $map{$_}";
}
while(my ($key, $value) = each %map) {
	say "key $key value $value";
}
reverse map (flip keys with values)
my %reverse = reverse %map;
deep copy hash
my %copy = %original;

date time

get date
my $time = localtime;
say "$time";
convert timestamp to date
$timestamp = `date +%s`;
my $date = localtime($timestamp);

boolean logic

auto conversions to boolean
if ( 0 ) {           // only number that is false
if ( 1 ) {           // true
if ( -1 ) {          // true

if ( '' ) {          // false
if ( '0' ) {         // false
if ( 'a' ) {         // true, if has any value other than '' and '0'

if ( $defined ) {    // see rules above
if ( $undefined ) {  // false
! to get inverse
my $inverse = ! $mybool
logical operators
[expr1] || [expr2]    # high presedence OR
[expr1] && [expr2]    # high presedence AND
[expr1] or [expr2]    # low presedence OR
[expr1] and [expr2]   # low presedence AND
$value1 // $value2    # returns first defined value

bitwise operators

$a & $b  # bitwise and
$a | $b  # bitwise or
$a ^ $b  # bitwise xor
$a << $n # bitwise shift n bits left
$a >> $n # bitwise shift n bits right
~ $a     # bitwise negation

subroutines

invoking a subroutine
&hello
hello
hello 1, 2, 3
hello(1, 2, 3)
hello world subroutine
sub hello {
	say "hello";
	foreach (@_) {
	say "\t" . "arg: $_";
	}
}
extracting parameters into variables
sub hello {
	my($a, $b) = @_;
	say "hello $a $b";
}
using shift
sub hello {
	while ($#_ > 0) {
		my $param = shift;
		say "arg: $param";
	}
}
retain state between subroutine calls
sub count {
	state $count = 0;
	$count += 1;
	say "invoked $count times";
}
example: trimming a string
sub trim {
	my $trimmed = $_[0] =~ s/\s++$//r ;
	$trimmed =~ s/^\s++//;
	$trimmed;
}

strict subroutine parameter definition

enable
use v5.20;
use feature qw(signatures);
no warnings qw(experimental::signatures);
subroutines with specified amount of parameters
sub noparams() {
sub single($one) {
sub multiple($one, $two) {
sub varargs($one, $two, @tail) {
sub varargsanonymous($one, $two, @) {
sub varargshash($one, $two, %hash) {
unnamed parameters
sub unnamed($, $) {
optional parameters without defaults
sub optional($=, $=) {
default values
sub defaults($one=1, $two=2) {
sub defaults($complex = somefunction() + 1) {

control flow

ternary operator

[test] ? [if_value] : [else_value]

statement modifiers

say "example" if $condition;
say "example" unless $condition;
say "repeat $_" foreach 1..10;
say "repeat $i" until $i++ > 10;
say "repeat $i" while $i++ < 11;

if

if ( [test] ) {
	....
} elsif ( [test] ) {
	....
} else {
	....
}
inverse
unless ( [test] ) {
	....
} elsif ( [test] ) {
	....
} else {
	....
}
null check (newer versions of perl will fail on undefined)
if ( defined $myvar ) {

while

while ( [condition] ) {
	# todo: code goes here
}
inverse
until ( [condition] ) {
	# todo: code goes here
}
piping a file to perl
cat [file] | perl [script]

 #!/usr/bin/perl
use 5.26.1;
my $i=0;
while (my $line = <STDIN>) {
	print "$i : $line";
	$i++;
}
iterate an array with index
while (($index, $value) = each @myarray) {
	# todo: code goes here
}

foreach

iterate an array
foreach (@myarray) {
	say "element: $_"
}
iterate an array with custom variable name
foreach my $element (@myarray) {
	say "element: $element"
}

for

for(my $i = 0; $i<11; $i++) {
	say "repeat $i";
}

loop control

exit from loop (break)
last;
last [label];
next iteration (continue)
next [label];
redo iteration (useful for invalid user input)
redo;
redo [label];
label
LABEL: while(1) {
	for(1..10) {
		say "loop $_";
		last LABEL if $_ eq 10;
	}
}

exception handling

catch an exception and extract the message
local $@;
my $undefined = eval { die "will be caught"; };
print "msg: $@";

built in subroutines

print error message and exit program
die [message]
run string as perl code
eval "say 'hello world';";

forking a process

defined(my $pid = fork) or die "fork error $!";
if($pid) {
	say "this is the parent process $$";
	waitpid($pid, 0);
} else {
	say "this is the child process $$";
}