print “what is your name? “; chomp($name = <STDIN>); # Program waits for user input from keyboard print “Welcome, $name, are your ready to learn Perl now? “; chomp($response = <STDIN>); $response=lc($response); # response is converted to lowercase if ($response eq “yes” or $response eq “y”){ print “Great! Let’s get started learning Perl by example.\n”; } else { print “O.K. Try again later.\n”; } $now = localtime; # Use a Perl function to get the date and time print “$name, you ran this script on $now.\n”;
How is Perl compiled?
Trick question, perl is not compiled but interpreted and partially compiled for errors.
Perl interpreter is found in unix system by typing where perl
… which may return /usr/local/bin/perl or /usr/bin/perl
This is why giving the path (#!/usr/local/bin/perl) of a Perl interpreter as boiler plate code is “required.”
print vs printf vs. sprintf
In summary, if you just want to output simple strings to the console, you can use print. If you need to output formatted text with placeholders for variables, use printf.
Parentheses are not required around the argument list
1 2 3 4 5 6 7
#print function print"Hello, world!\n";
#printf function my $name = "John"; my $age = 30; printf"My name is %s and I am %d years old.\n", $name, $age;
sprintf is similar to printf, except that printf outputs the formatted string to the console, while sprintf returns the formatted string as a value that can be stored in a variable or used as a value for some other purpose.
1 2 3 4 5 6 7 8 9 10 11 12 13
print"Hello, world\n";
print"Hello, ", " world\n";
print ("Its such a perfect day!\n"); # Parentheses optional
print"The date and time are: ", localtime(), "\n";
printf("Meet %s: Age %5d : Salary $%10.2f\n", "John", 40, 55000);
$string = sprintf("The name is: %10s\nThe number is: %8.2f\n", "Ellie", 33);
print $string; # sprintf allows you to assign the formatted string to a variable
OUTPUT
1 2 3 4 5 6 7 8 9 10 11 12 13
Hello, world
Hello, world
Its such a perfect day!
The date and time are: 1836231221230701
Meet John: Age 40 : Salary 010.2f
The name is: Ellie
The number is: 33.00
Numeric Literals
Name
Number Representation
Integer
6
Floating point
12.6
Scientific Notation
1e10
Scientific Notation
6.4E-33
Long Numbers (underscore)
4_348_348
Data Types and Variables
data types literally only include scalars, arrays, and associative arrays (hashes)*
Perl variables do not need to be declared.
Scalar data types only hold single values (strings, numbers, “value”).
Array data types are denoted with @ and elements are indexed starting at 0.
To print the entire array, use @nameOfArray. Add a double quote to add spaces between.
To add a new element to an array, you can expand an array by simply assigning a value to a new index. - Notice when we’re accessing single values, we use the scalar ($) symbol even though the variable “type” is an array.
#Assigning variables using other scalars as index print"\n"; print $A[$i];
#How do we find the length of array 'A'? #Method 1 -- use $# operator $len = $#A + 1; # array index begins at 0, so this returns the last index + 1 for size. print"\n$len";
#Method 2 -- call it array without quotes $len = @A; print"\n$len";
#However, calling @A in "" will print the entire array contents print"\n@A";
1 2 3 4 5
cost is 45.67 guna 4 4 guna guna cmu pgh
Resizing an Array & other print functionality
The # operator refers to array index.
1 2 3 4 5 6 7 8 9 10 11 12 13
#Declare another array called 'array' @array = (10, 12, 45); $#array = 1; # sets last index to 1
#What is the @array size?
print"The array contains @array \n" ;
$arraySize = @array; #notice how @array used like this return its size, but print @array returns the entire array print"The array size is: "; print $arraySize;
#Furthermore, notice the use of \ to negate the \@array in a double quoted print print"\nThe array \@array used in a print statement returns this instead: "; print @array;
1 2 3
The array contains 10 12 The array size is: 2 The array @array used in a print statement returns this instead: 1012
$#array = 1; sets the index of the last element in the @array to 1.
This means that the last element of the array is now the one at index 1. Since the array initially had three elements, setting the index of the last element to 1 effectively removes the element with value 45 from the array.
Variable Substitution
Variables inside strings are replaced with their value in double quotes.
Variable substitution does not occur for single quotes.
1 2 3 4 5 6
#Variable substitution -- double quote $stooge = "Larry"; print"$stooge is one of the three stooges.\n";
#single quote -- no substitution print'$stooge is one of the three stooges.\n';
1 2
Larry is one of the three stooges. $stooge is one of the three stooges.\n
Character Escapes
Character
Escape Sequence
Newline
\n
Tab
\t
Carriage return
\r
Numbers and Strings are Interchangeable!
If a scalar variable looks like a number and Perl needs a number, it will use the variable as a number!
1 2 3 4 5 6 7 8 9 10 11
# a number $a = 4;
# prints 22 print $a + 18;
# $b is a string but.. $b = "50";
# will print 40 print $b - 10;
if … else … statements
Similar to C/C++ - except that scope braces are REQUIRED!!
1 2 3 4 5 6 7 8 9 10
if ($os eq "Linux") { print"Sweet!\n"; } elsif ($os eq "Windows") { # no e!!! print"Time to move to Linux, buddy!\n"; } else { print"Hmm...!\n"; }
unless statement
1 2 3 4 5 6
unless ($condition) { # execute this block if $condition is false } else { # execute this block if $condition is true }
Note that you can also use the if statement with an inverted condition to achieve the same effect as an unless statement. For example, the following code is equivalent to the first example above:
1 2 3
if (! $condition) { # execute this block if $condition is false }
while Loop
While loop: Similar to C/C++ but again the braces are required!!
1 2 3 4 5
$i = 0; while ($i <= 1000) { print"$i\n"; $i++; }
until Loop
The until function evaluates an expression repeatedly until a specific condition is met.
Basically, executes if the condition is false. Stops when true. Opposite of while.
1 2 3 4 5
my $i = 1; until ($i > 10) { print"$i\n"; $i++; }
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
the variable $i to 1, and then repeatedly prints the value of $i and increments it by 1 until $i is greater than 10. At that point, the loop terminates and the script continues executing the next statement after the loop.
for loops
Like C++, notice how the scarlar is used
1 2 3
for ($i = 0; $i < 10; $i++) { print"$i\n"; }
for loops 2.0
- This one INCLUDES 10. So 0..10.
1 2 3
for $i (0..10) { print"$i\n" }
1 2 3 4 5 6 7 8 9 10 11
0 1 2 3 4 5 6 7 8 9 10
Control Inside a Loop
Where you would use continue in C, use next
The next statement is used to skip the current iteration of a loop and proceed to the next iteration. Where you would use break in C, use last
The last statement is used to exit a loop prematurely. For
• What is the output for the following?
1 2 3 4 5 6 7
for ($i = 0; $i < 10; $i++) { if ($i == 1 || $i == 3) { next; }
if ($i == 5) { last; }
print"$i\n"; }
1 2 3
0 2 4
Other loops
do {} while ()
Note that the do block is always executed at least once, regardless of whether the condition is true or false. This is because the condition is checked at the end of the block, after the code has been executed.
1 2 3 4 5 6
my $i = 0; do { print"$i\n"; $i++; } while ($i < 10);
foreach
In Perl, foreach is a looping construct used to iterate over elements of an array or a list. Here’s the basic syntax:
1 2 3
foreachmy $element (@array) { # do something with $element }
In this code, @array is an array variable containing a list of elements, and $element is a loop variable that takes on each value in the array, one at a time.Inside the loop block, you can perform some action using the current value of $element. For example, you might print the value of $element:
Note that the loop variable $element is a copy of the corresponding element in the array or list, so modifying $element inside the loop block does not affect the original array or list.
foreach can also be used with a list of values instead of an array:
print"Enter the number of the element you wish to view: "; chomp ($x=<STDIN>); @names=("Muriel","Gavin","Susanne","Sarah","Anna","Paul","Simon");
#We can use multiple indexes seperated by commas print"The first two elements are @names[0,1]\n";
#We can enter a range, which are inclusive. print"The first three elements are @names[0..2]\n";
#Notice that we use the scalar symbol even though names is an array because we are accessing one element only. print"You requested element $x who is $names[$x - 1]\n"; #starts at 0, if we enter 0, it'll show "simon"
print"The element before and after are @names[$x-2, $x]\n";
#We can combine range with indexes. print"The first, second, third, and fifth elements are @names[0..2,4]\n";
#Recall $#names returns the last index number print"a) The last element is $names[$#names]\n";
#Another method of accessing last index print"b) The last element is $names[-1]";
1 2 3 4 5 6 7 8
Enter the number of the element you wish to view: 3 The first two elements are Muriel Gavin The first three elements are Muriel Gavin Susanne You requested element 3 who is Susanne The element before and after are Gavin Sarah The first, second, third, and fifth elements are Muriel Gavin Susanne Anna a) The last element is Simon b) The last element is Simon
$myVar and @myVar
The two variables $myvar and @myvar are not, in any way, related.
#If the offset (2nd arguement) is negative, it'll begin at that point. #If the length (3rd argument) is negative, then it'll remove everything up to BUT NOT INCLUDING. @new = splice(@browser, 1, -1); print"@new\n";
##The following is equivalent to above @browser = ("NS","IE","Opera", "Safari"); @new = splice(@browser, -3, 2); # IE and Opera removed print"@new\n";
1 2 3
NS IE Opera Safari IE Opera IE Opera
Splice Function (What is the difference between the following codes?
print"Please tell me your name: "; $name = <STDIN>; # input also takes in new line character. print"Thanks for making me happy, $name!\n";
1 2
Thanks for making me happy, Mill !
How can we correct this?
1 2 3 4
print"Please tell me your name: "; $name = <STDIN>; chomp($name); #correction print"Thanks for making me happy, $name!\n";
1
Thanks for making me happy, Mill!
Sort
You can sort in ascending or descending order with numbers or strings. - Numbers will go by the size of the number, strings will go in alphabetical order - By default the sort() function, sorts in “ascending order”
The sort() function has three different syntaxes:
sort List
sort block, List
sort Subroutine, List
The code below shows a subroutine.
If SUBNAME or BLOCK is omitted, sorts in standard string comparison order. If SUBNAME is specified, it gives the name of a subroutine that returns an integer less than, equal to, or greater than 0, depending on how the elements of the list are to be ordered. (The <=> and cmp operators are extremely useful in such routines.)
subascend{ $a cmp $b }; ## returns -1 if a < b, 0 if a == b, 1 a > b
1
IE NS Opera
Built-in Sorting of Arrays (using sort() and <=>)
- default sort: sorts in a standard string comparisons order - sort LIST
usersub: create your own subroutine that returns an integer less than, equal to or greater than 0.
sort USERSUB LIST
The <=> and cmp operators make creating sorting subroutines very easy.
If you are comparing numbers, your comparisons operator should contain non-alphas, if you are comparing strings, the operator should contain alphas only.
Sorting Numerically
The sort function compares two variables, $a and $b The result is – 1 if $a is greater than $b – -1 if $b is greater than $a – 0 if $a and $b are equal
Sorting Example (Numeric)
The sort function is a built-in Perl function that sorts a list of elements. By default, it sorts elements in lexicographic (dictionary) order.However, you can provide a custom comparison function, as demonstrated in the code with {$a <=> $b}, to change the sorting behavior.
<=> is the spaceship operator in Perl. It is a numerical comparison operator that returns -1 if the left operand is less than the right operand, 0 if they are equal, and 1 if the left operand is greater than the right operand. It is often used in custom sorting functions.
# keys %countries, gets the keys #The $countries{$_} expression retrieves the value associated with the current key from the %countries hash. foreach (sort {$a <=> $b} keys %countries) { print"$_ $countries{$_} \n";
# sort by country name -- not too sure about this foreach (sort {$countries{$a} cmp $countries{$b} } keys %countries) { print"$_ $countries{$_}\n"; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
33 France 52 Mexico 64 New Zealand 212 Morroco 976 Mongolia France Mexico Mongolia Morroco New Zealand 33 France 52 Mexico 976 Mongolia 212 Morroco 64 New Zealand
#array of characters to string @stooge = ("c", "u", "r", "l", "y"); $string = join("", @stooge); # no space char was used here
print"$string";
1
curly
split
split allows you to create an array of elements by splitting a string every time a certain delimiter (a character of your choice) shows up within the string.
a delimiter is any kind of grammar sequence… (comma, space, tab, colon, semicolon, pipe, underscore, etc)
Notice in the split function that you place your delimiter between two forward slashes
You then place the string you want to split as the second argument
#split a string into words and put it into an array @array = split(/ /, "Larry Curly Moe"); # creates @array ("Larry", "Curly", "Moe") print"@array\n";
#split any non-space character @stooge = split(//, "curly"); # creates array @stooge with 5 elements: c, u, r, l, y print"@stooge\n";
#standard split on any character @array = split(/:/, "10:20:30:40"); # array has 4 elements: 10, 20, 30, 40 print"@array\n";
1 2 3
Larry Curly Moe c u r l y 10 20 30 40
string to array (cont.) use of \s+
Multiple white space characters: use \s+
1 2 3 4 5 6
#split on multiple white space #\s+ specifies one or more whitespace characters @array = split(/\s+/, "this is a \t test"); #array has 4 elements: this, is, a, test
print @array; # thisisatest
1
thisisatest
Question: What if we just use s+? Answer: just s+, it would match one or more occurrences of the letter ‘s’, not whitespace characters. Simply will use the char s as a delimiter. Result will be…
1 2 3 4
@array = split(/s+/, "this is a \t test"); #creates @array = ("thi", " i", " a \t te", "t")
print"@array\n";
1
thi i a te t
default split() behavior
split without any arguements in Perl defaults to splitting the $_ variable on whitespace. This is equivalent to using split(/\s+/, $_).
For example,
1 2 3 4 5 6 7 8 9 10 11 12 13 14
my $input_string = "this is an example string";
# Using the default behavior of split: { local $_ = $input_string; my @fields_default = split; print"Using default split behavior:\n"; printjoin(", ", @fields_default), "\n"; }
# Using explicit pattern and string for split: my @fields_explicit = split(/\s+/, $input_string); print"Using explicit pattern and string:\n"; printjoin(", ", @fields_explicit), "\n";
1 2 3 4
Using default split behavior: this, is, an, example, string Using explicit pattern and string: this, is, an, example, string
Quick Review of ‘local’
In Perl, the local keyword is used to create a temporary local value for a global variable within a limited scope (usually within a block or a subroutine). This local value is only used within that specific scope, and once the control leaves that scope, the global variable is restored to its previous value.
1 2 3 4 5 6
{ local $_ = $input_string; my @fields_default = split; print"Using default split behavior:\n"; printjoin(", ", @fields_default), "\n"; }
The local $_ = $input_string; line temporarily assigns the value of $input_string to the global $_ variable within the block enclosed by {}. The split function, when used without arguments, operates on the $_ variable, which now contains the value of $input_string. After the block is executed, the original value of $_ (if any) is restored.
The purpose of using local here is to avoid modifying the global $_ variable outside of the block, ensuring that any changes made within the block do not affect the variable’s value in other parts of the program.
Quick Review of ‘my’ keyword
In Perl, the my keyword is used to declare a lexically scoped variable. A lexically scoped variable is only accessible within the block or subroutine it is declared in, and it is not visible or accessible outside of that scope.
Using the my keyword helps you create more modular and maintainable code by preventing accidental modification of variables from other parts of your code. It also allows you to reuse variable names without conflicts.
Here’s an example to demonstrate the usage of the my keyword:
1 2 3 4 5 6 7 8 9 10
subsome_function{ my $local_var = "Hello, World"; print"Inside the function: $local_var\n"; }
#prints fine some_function();
# This will cause an error/will not print, as $local_var is not accessible print"Outside the function: $local_var\n";
1 2
Inside the function: Hello, World Outside the function:
Perl Associative Arrays (Hashes)
Why use hashes?
When you want to look something up by a keyword.
Supposed we wanted to create a program which returns the name of the country when given a country code.
We’d input ES, and the program would output Spain.
With a hash, perl reorders elements for quick access
Associative arrays are created with key/value pairs.
Key is a text string used to access the value.
A value is the value of the variable stored.
Each key must be unique. If you define a certain key twice, the second value overwrites the first
each %family_name: The each function is used to iterate through a hash in Perl. When called in list context, it returns a key-value pair from the hash. The iteration continues until all key-value pairs have been returned. After the last key-value pair, the each function returns an empty list.
Defining Associative Arrays and Access Elements in Hash
# To access an element, you use your key string in place of a number print $our_friends{'good'}; print"\n";
$good_friend = $our_friends{'good'};
print"I have a good friend named $good_friend.\n";
Access Elements in Hash (cont.)
All the keys
The keys appear in a seemingly “reverse” order, but it’s essential to understand that Perl hashes do not maintain any specific order. The internal order of a hash is determined by the hashing algorithm and other factors, so the order in which keys are stored or returned may not match the order in which they were added. Thus, when you print the keys, the order is not guaranteed to be the same as the order you defined them.
All the values
Accessing parts of the hash
Accessing elements by forcing scalar
The scalar function is used to force a list context into a scalar context. When applied to the list of keys from the %countries hash, it returns the number of elements in the list, which corresponds to the number of keys in the hash.
postfix if-statement
This line uses a postfixed if conditional statement to control the execution of the print function. The print function will only execute if the condition following the if statement is true. In this case, the condition is checking if the key ‘NL’ exists in the %countries hash. If it does, the line “It’s there! \n” will be printed, followed by a newline character.
while (($key, $value) = each %our_friends) { print"$key => $value\n"; }
1 2
good => Robert best => Don
Scoping Rule with ‘my’ % ‘local’
Scope (visibility) of a variable
Static scoping: my
my creates a variable only accessible within the block or file in which they are declared.
a block is often declared with braces {}
Dynamic scoping: local
local variables can affect outside its block.
Often times, it suspends the use of a global variable and uses a local variable (declared by local).
This is often better understood using a run-time stack.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#1/user/bin/perl
$x = 1; # global variable is declared (scope is file)
subfoo{ # subroutine print"$x\n"; } # what happens if we use 'my' vs. 'local' subbar{ $x = 2; foo(); }
&foo; # since $x = 1 is declared, it will use this global variable &bar; # bar is called, which replaces $x = 1 with $x = 2; # -- will print 2 when (foo()) is called inside bar &foo; # since global variable $x = 2, 2 will print
$x = 1; # global variable is declared (scope is file)
subfoo{ # subroutine print"$x\n"; } # what happens if we use 'my' vs. 'local' subbar{ local $x = 2; foo(); }
&foo; # prints 1
#local $x = 2; temporarily replaces global $x = 1 (until the subroutine ends) #therefore, when foo is called, $x = 2 is the current variable. # foo() is returned and removed from the run stack. # then bar() is returned and removed from the run stack &bar; #prints 2
# because bar() is removed from the run stacl, $x = 2 is no more. # the global variable $x = 1 is the value. Hence... &foo; #prints 1
&fun1; # as long as we're in the subroutine, $var = 10; will replace the global $var = 5 # ask yourself--are we still in the subroutine? # 1st print: are we in subroutine? yes. so print: 10 # &fun2; are we in subroutine? yes. so $var++ iterates the local $var = 10 -> local $var = 11 # 2nd print: (are we in the subroutine?) yes. prints 11 # 3rd print: (are we in the subroutine? NO.) $var = 5; prints 5
length() function returns number of characters in a string variable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
$ice = "cold";
# length function returns number of characters in a string # length() works by creating a 'scalar' context for its parameters $length_ice = length($ice);
print $length_ice, "\n"; # prints 4
#what will be the output? $my_string = "abc"; @my_array = (1,2,3,4,5);
#since length creates a scalar context print (length $my_string, "\n"); # prints 3 #### UNDEFINED BEHAVIOR
print (length @my_array); # prints 5? no... #prints 1...
the length function is only meant to be used on strings– otherwise, unexpected behavior.
Substring ( substr() )
substr($string_variable, start number, length)
$string_variable is the string intended to be substr’d
2nd parameter is the indexed value (starting at 0)
3rd parameter is amount you wish to take
substr() function brings on an important distinction when it comes to DESTRUCTIVE functions vs. non-destructive - substr() is a non-destructive function.
1 2 3 4 5
$ice = "cold"; $age = substr($ice, 1, 3);
print"It sure is $ice out here today\n"; print"I wonder if I am $age enough to play in the snow?";
this looks at chomp(), STDIN, a bit of paramatching w/ a target =~, and the use of default sort (alphabet) and then reverse
# What is the purpose of chomp again? chomp ($find = <STDIN>);
# Make sure everything is in uppercase # This is a direct translation, any lowercase letters will be converted to upper. # =~ spacing MATTERS here. Makes $find the target string. $find =~ tr/a-z/A-Z/;
print"$countries{$find} has the code $find\n";
# sorts in alphabet order first, but then it's reversed. So it'll print # NL -> MC -> ES -> DE -> BE? foreach (reversesortkeys %countries) { print"The key $_ contains $countries{$_}\n"; }
1 2 3 4 5 6 7
Enter the country code: NL The Netherlands has the code NL The key NL contains The Netherlands The key MC contains Monaco The key ES contains Spain The key DE contains Germany The key BE contains Belgium
Subroutines
User-defined functions in Perl
Lets us recycle one chunck of code multiple times.
Name of subrountines is another Perl identifier
(only limitation is can’t start with digit)
- To invoke subroutine, place & in front of its name.
In Perl, the special variable @_ represents the list of arguments passed to a subroutine.
1 2 3 4 5 6 7 8 9
$n = &max(10, 15); print $n;
submax{ my ($m, $n) = @_; # new private variable for this block
if ($m > $n) { $m } else { $n } }
1
15
Persistent, Private Variable
basically the static variable in C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14
use feature 'state';
submarine{ state $n = 0; #static (private, persistent) variable $n $n += 1; print"Hello, sailor number $n!\n"; }
for ($i = 0; $i < 3; $i++) { &marine; }
&marine; &marine;
1 2 3 4 5
Hello, sailor number 1! Hello, sailor number 2! Hello, sailor number 3! Hello, sailor number 4! Hello, sailor number 5!