Perl Tutorial: A Basic Program


Here is the basic perl program that we'll use to get started.
#!/usr/local/bin/perl## Program to do the obvious#print 'Hello world.'; # Print a message
Each of the parts will be discussed in turn.

The First Line

Every perl program starts off with this as its very first line:

#!/usr/local/bin/perl
although this may vary from system to system. This line tells the machine what to do with the file when it is executed (ie it tells it to run the file through Perl).

Comments and Statements

Comments can be inserted into a program with the # symbol, and anything from the #to the end of the line is ignored (with the exception of the first line). The only way to stretch comments over several lines is to use a # on each line.
Everything else is a Perl statement which must end with a semicolon, like the last line above.

Simple Printing

The print function outputs some information. In the above case it prints out the the literal string Hello world. and of course the statement ends with a semicolon.
You may find the above program produces an slightly unexpected result. So the next thing to do is to run it.


Running the Program


Type in the example program using a text editor, and save it. Emacs is a good editor to use for this because it has its own Perl mode which formats lines nicely when you hit tab (use `M-x perl-mode'). But as ever, use whichever you're most comfortable with.After you've entered and saved the program make sure the file is executable by using the command
chmod u+x progname
at the UNIX prompt, where progname is the filename of the program. Now to run the program just type any of the following at the prompt.

perl progname./prognameprogname
If something goes wrong then you may get error messages, or you may get nothing. You can always run the program with warnings using the command
perl -w progname
at the prompt. This will display warnings and other (hopefully) helpful messages before it tries to execute the program. To run the program with a debugger use the command

perl -d progname
When the file is executed Perl first compiles it and then executes that compiled version. So after a short pause for compilation the program should run quite quickly. This also explains why you can get compilation errors when you execute a Perl file which consists only of text.
Make sure your program works before proceeding. The program's output may be slightly unexpected '-' at least it isn't very pretty. We'll look next at variables and then tie this in with prettier printing.

Scalar variables


The most basic kind of variable in Perl is the scalar variable. Scalar variables hold both strings and numbers, and are remarkable in that strings and numbers are completely interchangable. For example, the statement

$priority = 9;sets the scalar variable $priority to 9, but you can also assign a string to exactly the same variable:
$priority = 'high';Perl also accepts numbers as strings, like this:
$priority = '9';$default = '0009';and can still cope with arithmetic and other operations quite happily.In general variable names consists of numbers, letters and underscores, but they should not start with a number and the variable $_ is special, as we'll see later. Also, Perl is case sensitive, so $a and $A are different.

Operations and Assigments

Perl uses all the usual C arithmetic operators:
$a = 1 + 2; # Add 1 and 2 and store in $a$a = 3 - 4; # Subtract 4 from 3 and store in $a$a = 5 * 6; # Multiply 5 and 6$a = 7 / 8; # Divide 7 by 8 to give 0.875$a = 9 ** 10; # Nine to the power of 10$a = 5 % 2; # Remainder of 5 divided by 2++$a; # Increment $a and then return it$a++; # Return $a and then increment it--$a; # Decrement $a and then return it$a--; # Return $a and then decrement itand for strings Perl has the following among others:
$a = $b . $c; # Concatenate $b and $c$a = $b x $c; # $b repeated $c timesTo assign values Perl includes
$a = $b; # Assign $b to $a$a += $b; # Add $b to $a$a -= $b; # Subtract $b from $a$a .= $b; # Append $b onto $aNote that when Perl assigns a value with $a = $b it makes a copy of $b and then assigns that to $a. Therefore the next time you change $b it will not alter $a.Other operators can be found on the perlop manual page. Type man perlop at the prompt.
Interpolation

The following code prints apples and pears using concatenation:
$a = 'apples';$b = 'pears';print $a.' and '.$b;It would be nicer to include only one string in the final print statement, but the line
print '$a and $b';prints literally $a and $b which isn't very helpful. Instead we can use the double quotes in place of the single quotes:
print "$a and $b";The double quotes force interpolation of any codes, including interpreting variables. This is a much nicer than our original statement. Other codes that are interpolated include special characters such as newline and tab. The code \n is a newline and \t is a tab.
Exercise

This exercise is to rewrite the Hello world program so that (a) the string is assigned to a variable and (b) this variable is then printed with a newline character. Use the double quotes and don't use the concatenation operator. Make sure you can get this to work before proceeding.

Array Variables


A slightly more interesting kind of variable is thearray variable which is a list of scalars (ie numbers and strings). Array variables have the same format as scalar variables except that they are prefixed by an @ symbol. The statement

@food = ("apples", "pears", "eels");@music = ("whistle", "flute");assigns a three element list to the array variable @food and a two element list to the array variable @music.The array is accessed by using indices starting from 0, and square brackets are used to specify the index. The expression

$food[2]returns eels. Notice that the @ has changed to a $ because eels is a scalar.
Array Assignments

As in all of Perl, the same expression in a different context can produce a different result. The first assignment below explodes the @music variable so that it is equivalent to the second assignment.
@moremusic = ("organ", @music, "harp");@moremusic = ("organ", "whistle", "flute", "harp");This should suggest a way of adding elements to an array. A neater way of adding elements is to use the statement
push(@food, "eggs");which pushes eggs onto the end of the array @food. To push two or more items onto the array use one of the following forms:
push(@food, "eggs", "lard");push(@food, ("eggs", "lard"));push(@food, @morefood);The push function returns the length of the new list.To remove the last item from a list and return it use the pop function. From our original list the pop function returns eels and @food now has two elements:

$grub = pop(@food); # Now $grub = "eels"It is also possible to assign an array to a scalar variable. As usual context is important. The line

$f = @food;assigns the length of @food, but
$f = "@food";turns the list into a string with a space between each element. This space can be replaced by any other string by changing the value of the special$" variable. This variable is just one of Perl's many special variables, most of which have odd names.Arrays can also be used to make multiple assignments to scalar variables:

($a, $b) = ($c, $d); # Same as $a=$c; $b=$d;($a, $b) = @food; # $a and $b are the first two # items of @food.($a, @somefood) = @food; # $a is the first item of @food # @somefood is a list of the # others.(@somefood, $a) = @food; # @somefood is @food and # $a is undefined.The last assignment occurs because arrays are greedy, and @somefood will swallow up as much of @food as it can. Therefore that form is best avoided.Finally, you may want to find the index of the last element of a list. To do this for the @food array use the expression

$#food
Displaying Arrays

Since context is important, it shouldn't be too surprising that the following all produce different results:
print @food; # By itselfprint "@food"; # Embedded in double quotesprint @food.""; # In a scalar context
Exercise

Try out each of the above three print statements to see what they do.

File handling


Here is the basic perl program which does the same as the UNIX cat command on a certain file.



#!/usr/local/bin/perl## Program to open the password file, read it in,# print it, and close it again.$file = '/etc/passwd'; # Name the fileopen(INFO, $file); # Open the file@lines = <INFO>; # Read it into an arrayclose(INFO); # Close the fileprint @lines; # Print the arrayThe open function opens a file for input (i.e. for reading). The first parameter is the filehandle which allows Perl to refer to the file in future. The second parameter is an expression denoting the filename. If the filename was given in quotes then it is taken literally without shell expansion. So the expression '~/notes/todolist' will not be interpreted successfully. If you want to force shell expansion then use angled brackets: that is, use <~/notes/todolist> instead.
The close function tells Perl to finish with that file.
There are a few useful points to add to this discussion on filehandling. First, the open statement can also specify a file for output and for appending as well as for input. To do this, prefix the filename with a > for output and a >> for appending:

open(INFO, $file); # Open for inputopen(INFO, ">$file"); # Open for outputopen(INFO, ">>$file"); # Open for appendingopen(INFO, "<$file"); # Also open for inputSecond, if you want to print something to a file you've already opened for output then you can use the print statement with an extra parameter. To print a string to the file with the INFO filehandle use

print INFO "This line goes to the file.\n";Third, you can use the following to open the standard input (usually the keyboard) and standard output (usually the screen) respectively:

open(INFO, '-'); # Open standard inputopen(INFO, '>-'); # Open standard outputIn the above program the information is read from a file. The file is the INFO file and to read from it Perl uses angled brackets. So the statement
@lines = <INFO>;reads the file denoted by the filehandle into the array @lines. Note that the <INFO> expression reads in the file entirely in one go. This because the reading takes place in the context of an array variable. If @lines is replaced by the scalar $lines then only the next one line would be read in. In either case each line is stored complete with its newline character at the end.

Control Structures


More interesting possiblities arise when we introduce control structures and looping. Perl supports lots of different kinds of control structures which tend to be like those in C, but are very similar to Pascal, too. Here we discuss a few of them.

foreach

To go through each line of an array or other list-like structure (such as lines in a file) Perl uses the foreach structure. This has the form
foreach $morsel (@food) # Visit each item in turn # and call it $morsel{ print "$morsel\n"; # Print the item print "Yum yum\n"; # That was nice}The actions to be performed each time are enclosed in a block of curly braces. The first time through the block $morsel is assigned the value of the first item in the array @food. Next time it is assigned the value of the second item, and so until the end. If @food is empty to start with then the block of statements is never executed.
Testing

The next few structures rely on a test being true or false. In Perl any non-zero number and non-empty string is counted as true. The number zero, zero by itself in a string, and the empty string are counted as false. Here are some tests on numbers and strings.
$a == $b # Is $a numerically equal to $b? # Beware: Don't use the = operator.$a != $b # Is $a numerically unequal to $b?$a eq $b # Is $a string-equal to $b?$a ne $b # Is $a string-unequal to $b?You can also use logical and, or and not:

($a && $b) # Is $a and $b true?($a || $b) # Is either $a or $b true?!($a) # is $a false?
for

Perl has a for structure that mimics that of C. It has the form
for (initialise; test; inc){ first_action; second_action; etc}First of all the statement initialise is executed. Then while test is true the block of actions is executed. After each time the block is executed inc takes place. Here is an example for loop to print out the numbers 0 to 9.
for ($i = 0; $i < 10; ++$i) # Start with $i = 1 # Do it while $i < 10 # Increment $i before repeating{ print "$i\n";}
while & until

Here is a program that reads some input from the keyboard and won't continue until it is the correct password
#!/usr/local/bin/perlprint "Password? "; # Ask for input$a = <STDIN>; # Get inputchop $a; # Remove the newline at endwhile ($a ne "fred") # While input is wrong...{ print "sorry. Again? "; # Ask again $a = <STDIN>; # Get input again chop $a; # Chop off newline again}The curly-braced block of code is executed while the input does not equal the password. The while structure should be fairly clear, but this is the opportunity to notice several things. First, we can we read from the standard input (the keyboard) without opening the file first. Second, when the password is entered $a is given that value including the newline character at the end. The chop function removes the last character of a string which in this case is the newline.To test the opposite thing we can use the until statement in just the same way. This executes the block repeatedly until the expression is true, not while it is true.
Another useful technique is putting the while or until check at the end of the statement block rather than at the beginning. This will require the presence of the do operator to mark the beginning of the block and the test at the end. If we forgo the sorry. Againmessage in the above password program then it could be written like this.

#!/usr/local/bin/perldo{ "Password? "; # Ask for input $a = <STDIN>; # Get input chop $a; # Chop off newline}while ($a ne "fred") # Redo while wrong input
Exercise

Modify the program from the previous exercise so that each line of the file is read in one by one and is output with a line number at the beginning. You should get something like:
1 rootYpYXm/qRO6N2:0:0:Super-User:/:/bin/csh2 sysadm:*:0:0:System V Administration:/usr/admin:/bin/sh3 diag:*:0:996:Hardware Diagnostics:/usr/diags:/bin/cshetcYou may find it useful to use the structure
while ($line = <INFO>){ ...}When you have done this see if you can alter it so that line numbers are printed as 001, 002, ..., 009, 010, 011, 012, etc. To do this you should only need to change one line by inserting an extra four characters. Perl's clever like that.


› See More: Perl Tutorial: A Basic Program I