Introduction to Perl

What is perl?

Perl is a programming language developed by Larry Wall in 1986. (long before the web as most people know it!!) It was originally designed as a tool for unix system administrators for handling text editing and system administration tools. It is still heavily used for this purpose. The original target audience for the language was unix system administrators who usually know C and a smattering of other languages, and are extremely comfortable with UNIX. You can become very good at perl without this background, but it's helpful to keep in mind as you explore the language. Perl has a mystique as a hacker's language. It has a sort of 'wild-west, off-road, bubble-gum and bailing wire' kind of feel to it. This means that it is extremely popular with programmers who want to do things their own way, but it can make the code more difficult to read than languages with a more dignified pedigree such as Java. At first, reading perl code can be incredibly intimidating, but you will find that with some practice you will find it a very nice language to work with.

One of the reasons perl was developed is that many of the other languages used in the unix world (particularly c and c++) require a lot of work when dealing with text. Wall wanted a language that could deal with text very easily, and that could automate a lot of the kinds of things programmers do with text, like search and replace, saving and loading files, making lists, and so on.

When the web began to take off, programmers started looking for languages that could give them power on the server. They had access to an interface called CGI (see the next chapter for details) that would allow them to use any language they wanted as long as it could be run on the server. In the early days, nearly all the servers ran unix, and many of the webmasters were also unix system administrators. They quickly discovered that perl was an ideal language for server-side web programming.

Why is perl so popular as a server language?

Although there are some other choices, perl is still extremely popular as a server-side programming language. There are many reasons for this:

Perl description

Perl is derived from C, so if you have familiarity with another C-like language such as javascript C/C++, or Java, you will find a lot of similarities. You will find, though, that some things are different. In the rest of this chapter, we will take a look at the main tools present in any programming language, and see how perl treats these concepts.

variables

Of course variables are central to any language. Perl has an interesting perspective on variables. It does not require you to explicitly declare them, or determine their type. The type of a variable is determined by the context in which it is used. This can be difficult to get used to, but you will find that most of the time it is reasonably natural.

scalar variables

Variables in perl all begin with a special identifying character. This character is used to give some important information about the variable. Most variables in perl start with the $ character. This stands for scalar. A scalar variable is one that has one value a a time. (in other words, not an array or structure). To create a scalar variable, you can just refer to it, and it will be created on the fly.

$userName = "George";
$x = 7;
Notice that you can assign a string or an integer value to a variable. The type of the variable is flexible. Sometimes it will be considered string, and sometimes numeric. This is disturbing at first, but you'll get used to it.

This process of creating variables by just naming them is called implicit variable declaration It's easy, but there are some dangers. You have to be very careful about spelling, because if you mispell a variable, you will accidentally create a completely new variable. For example, look at the following code:

$userName = "George";
print $username;
The program would print out the value 0, because $userName and $username are NOT the same variable! When the language encounters the second line, it will see that it is required to print out the value of the variable $username, which currently doesn't exist. It will cheerfully create the new variable with the default value of 0. It will then print out the value of the new variable, which has absolutely no relationship to $userName with a capital N. When your code starts acting strange, and you see a lot of zeroes where you are expecting other values, this is a good thing to look for.

Another very common error is forgetting the "$" at the beginning of the variable name. When you do this, perl will not realize you are talking about a variable, and will presume that the word you typed was some kind of function. You will get unpredictable results, and they will almost never be pleasant. Be very careful to remember that variables in perl start with $ or another special character.

variable interpolation

One of the nicest things about perl variables is the fact that they can be interpolated into other strings easily. Here's an example:

$userName = "George";
print "Hi, $userName!";
The interesting thing about this example is that we did not need to do any string concatenation. The same code in javascript might look something like this:
var userName = "George";
alert("Hi, " + userName + "!");
In most languages, (like javascript) we have to concatenate string literals and string variables together. That is not necessary in perl, although it can be done. Because perl uses the special $ identifier for variables, it can automatically recognize that a variable is part of a string, and will replace the variable name with the value of that variable.

input and output

There are a number of ways to do input and output in perl, but we will look at the most basic of them here.

the print statement

Print is the basic output statement. It is extremely flexible. We can print complex values, strings and numbers very easily. We can also interpolate special control characters such as "\t" (tab) and "\n" (newline). These characaters will insert the appropriate control code into the output so a tab or carriage return will occur. You will see many examples of print throughout this chapter.

<STDIN>

When we use perl on the command line (as we are doing today), we want to be able to get some orm of input from the user. To do so, we use a special 'handle' called <STDIN> This stands for standard input, and represents anything typed into the keyboard. To get input, you should first print some question, then assign the value of <STDIN> to a variable. Program control will halt until the user has pressed the enter key, and whatever string they typed will be transferred to the variable. Important!!! The carriage return that ended the string is also included in the variable, so we usually use the chop function to remove that trailing value.

Here's an example of input and output:
#input and output demo
print "Hello there.  What is your name? ";
$userName = <STDIN>;

#note that this will come out on two lines!!
print "Hi $userName, nice to meet you. \n";

#kill off the trailing carriage return
chop $userName;

#try the output again:
print "Hi $userName, nice to meet you. \n";
and the output:
Hello there.  What is your name? Andy
Hi Andy
, nice to meet you. 
Hi Andy, nice to meet you. 

Operators in perl

Most of the perl operators are very familiar to those who have already experienced another c-like language. Perl uses most of the familiar mathematical operators like +, -, /, and *, as well as the increment operators like +=, ++, and the like. The following math program will illustrate the various math operators:

$number = 1;
print $number;
print "\n";

$number++;
print $number;
print "\n";

$number += 5;
print $number;
print "\n";

print $number ** 2;
print "\n";
and the output of this program:
1
2
7
49

discussion of math operators

These are pretty straightforward. The "++" operator adds one to a variable, and the "+=" operator allows us to increment by some other value. "--" and "-=" work in pretty much the same way, except of course they subtract. The "**" operator is used for exponentiation. In addition, there are a number of mathematical functions that you can look up when you need them.

Here's a few of the most useful mathematical functions: Here is a simple program that illustrates some of these functions...
#mathFunc.pl
#demonstrates math functions in perl

print "the sine of pi is ";
print sin 3.14159;
print "\n";

#seed random generator;
srand;

#get a value between 0 and 1;
$myNumber = rand;
print $myNumber;
print "\n";

#make that number between 0 and 100 by multiplying
$myNumber *= 100;
print $myNumber;
print "\n";

#get the integer version of the number
$myNumber = int $myNumber;
print $myNumber;
print "\n";
...and here's the output:
the sine of pi is 2.65358979335273e-06
here's a random number between 1 and 10: 0.792877197265625
79.2877197265625
79

string operators

perl has a number of operators available for dealing with strings, as you might expect in a language devoted to string manipulation. Perhaps the single most common string operation is concatenation, or joining strings together. Many languages use the + sign for string concatenation, but perl uses the period (.) instead. This is important, because variables do not have an explicit type in perl. The type is always determined in the context of the expression, so the kinds of operators you use determine what the variable types are. This is not intuitive, but an example will help:

#initialize
$x = 3;
$y = 5;

#add with a MATH operator, so x and y must be numbers
print "x + y = ";
print $x + $y;
print "\n";

#concatenate with a STRING operator, so x and y are seen as strings
print "x . y = ";
print $x . $y;
print "\n";
The results would be
x + y = 8
x . y = 35

The important concept here is that using a math operator implies that the variables around that operator should be interpreted as numbers. Using a string operator tells the perl interpreter that the variables around the operator are strings. It is not the variables themselves that are a particular type, but the way they are used. Any scalar variable could be interpreted either as a string or a number, with sometimes confusing results.

In additon to the "." operator, perl has a ".=" operator, which is used to append data to the end of a string variable. These two lines are identical:

$theVariable = theVariable . " is a goof!";
$theVariable .= "is a goof!";

Perl also has a rich toolbox of functions for manipulating strings. Here is a brief overview of some of them:

Here's a program which demonstrates some of these features:
#strings.pl
$theString = "Twas brillig and the slithy toves";

print "brillig is at character: ";
print index $theString, "brillig";
print "\n";

print "in all lowercase: ";
print lc $theString;
print "\n";

print "with the first character capitalized: ";
print ucfirst $theString;
print "\n";

print "all in caps: ";
print uc $theString;
print "\n";

print "first char in caps: ";
print ucfirst $theString;
print "\n";

print "Length: ";
print length $theString;
print " characters. \n";

print "first ten characters: ";
print substr $theString, 0, 10;
print "\n";
...and here's the output of that program:
brillig is at character: 5
in all lowercase: twas brillig and the slithy toves
with the first character capitalized: Twas brillig and the slithy toves
all in caps: TWAS BRILLIG AND THE SLITHY TOVES
first char in caps: Twas brillig and the slithy toves
Length: 33 characters. 
first ten characters: Twas brill

Comparison operators

This characteristic of operators determining variable type also extends to the comparison operators. Examine the following code:

$password = "garbage";

if ($password == "abracadabra"){
  print "welcome in!!";
} else {
  print "the password is incorrect");
} # end if
Take a careful look at the code and determine how it would act. The password is pre-set to the wrong answer, then it is compared to "abracadabra". You might be surprised to see the outcome of this code:
welcome in!!!
Apparently, we were allowed in, even though the password was incorrect. Before we explain why that code did not work, here is a variation that will act as expected, with one simple but very important difference:
$password = "garbage";

# note that we replace == with eq
if ($password eq "abracadabra"){
  print "welcome in!!";
} else {
  print "the password is incorrect");
} # end if
and the result now:
the password is incorrect
This second version worked correctly, with a change in the comparison operator. "eq" stands for 'is equal to' just as "==" does, but in perl, "==" is a numeric comparison and "eq" is a string comparison. In the first example, the line that looked like this:
if ($password == "abracadabra"){
has a condition with the "==" operator in it. Since this is a numeric operator, perl automatically tried to convert the value of $password to a number. There are no obvious numeric digits in "garbage", so the numeric value of $password is the number 0. The numeric value of the string "abracadabra" is also zero, as there are no digits in it, so since both are zero, they are equal, and the condition is evaluated as true. The moral of the story is that there are different types of operators for numbers and strings, and if you forget this fact, you will have very strange results.

Here's a chart to help you keep the comparisons straight:
comparison numeric string
is equal to == eq
is not equal to != ne
is less than < lt
is greater than > gt
less than or equal to <= le
greater than or equal to >= ge
You have probably figured out the pattern. The numeric operators use mathematical symbols, and the string operators use string symbols. It's much easier than you might think at first, but almost everybody accidentally uses the wrong comparison sometime, and has a hard time debugging the program.

Control structures

As long as you remember the comparison operators, all the control structures are pretty straightforward. Here's a synopsis:

if statement

If statements in perl are much like in any other C-like language. They require a condition, and will execute an instruction or a series of instructions within {} if that condition is evaluated to true. You can also have an else clause, which will execute only if the condition is evaluated to false. In addition, perl supports an elsif structure that allows you to have a multiple - condition if structure. Here's a program that demonstrates the if structure in perl:

#if.pl
#demonstrates variations of the if statement in perl

print "What's your name? ";
$userName = <STDIN>;
chop $userName;

if ($userName eq "Bill Gates"){
    print "Even YOU use perl?!? \n";
} else {
    print "have you seen Bill around? \n";
} # end if

print "What month is your birthday? ";
$birthday = <STDIN>;
chop $birthday;
$birthday = uc $birthday;

if ($birthday eq "JANUARY"){
    print "Your birthstone is Garnet \n";
} elsif ($birthday eq "FEBRUARY"){
    print "Your birthstone is Amethyst \n";
} elsif ($birthday eq "MARCH"){
    print "Your birthstone is Aquamarine \n";
} elsif ($birthday eq "APRIL"){
    print "Your birthstone is Diamond \n";
} else {
    print "I don't know your birthstone. \n";
} # end if structure
and as usual, the output:
What's your name? Andy
have you seen Bill around? 
What month is your birthday? January
Your birthstone is Garnet 

Laboratory assignment

re-write the program you wrote in the conditions chapter as a command line perl program. Here are the assignments again:
  1. Write a password program. It should ask the user for a password, and if the user gets it right, congratulate her. If she gets it wrong, tell her so.
  2. Improve the password program so it repeats if the user gets the password incorrectly keep asking for the password until the user gets it right.
  3. Improve the above program so the user can get it wrong up to three times. If they do not get the password after three tries, exit the program.
  4. Write a simple quiz program that asks the user a math question, then evaluates the answer. If the user got it right, tell her so. If she got it wrong, give her another chance.
  5. Write a program that generates a multiplication table. Ask the user for a number, and show that number multiplied by 1 through 10.
  6. Write a more complete multiplication table that shows all the values of 1-10 multiplied by each other in a table. HINT: you will need two for loops nested inside each other!! Use the \t (tab) and \n characters to format the table.
  7. Write a number guessing game. The computer will come up with a random integer between 1 and 100, and the user will make guesses about the number. After the user guesses, the computer will tell her whether she is too high, too low, or has hit the number. The program should keep track of the number of turns it took to guess the number.
  8. Write the same game as the last problem, but this time reverse the logic. The player will come up with the random number, and the program will guess, after which the player will tell the computer 'too high, too low, or just right'. Hint: think carefully about the smartest way to play the game as the user and analyze how you came to the numbers you guessed.
  9. Write a program that converts a number from decimal to binary. Ask the user for a base 10 number below 64, then use a loop to calculate the digits of binary. DO NOT use the automatic conversion feature built into perl (although you can use it to check your answers). Hint: Make the binary output a string value, and use the ** operator inside a loop to determine whether each digit will be 0 or 1. Then concatenate the string digits together for the result.