Week 2 - January 26, 1999


2.1 The Structure of a Perl Program

The structure of a Perl program looks like the one of a C program. We have a MAIN block and functions. What is different is that we do not have to declare the functions in advance nor the variables that we have to pass to the functions. Always, the first line in a Perl program should be the line that calls the Perl interpreter.

#!/usr/local/bin/perl

Then, in any order, we can have our functions (if any) and the MAIN block, which should appear like

MAIN:
{
   ....
   ....
}

Please note the : sign after MAIN. The functions are declared in a similar way, but instead of using : we use the sub keyword

sub MyFunction
{
   ....
   ....
}

To call a function in Perl, we use the name of the function preceded by the & sign.

&MyFunction("123","Bogdan","CS246");

We will discuss later how the parameters are passed to the funtion.

2.2 Perl Data Types

2.2.1 Scalars

Most programming languages have various data types, and Perl is no exception. Unlike C, Perl has one important data type, the scalar, who replaces many of the common data types found in other languages. A scalar is simply a single item: integer, floating point number, character, string, pr boolean. The precise type need not be specified in advance. The scalars automatically convert between different types as needed.

$number = 246;                  # $number is a number, as expected
$title = "Internet Paradigms";  # just another plain string
$course = "244";                # another string
print $course +2;               # prints 246 - automatic string/number conversion
$scourse = "CS" . $number;      # .(dot) is string concatenation; $course is "CS246"
                                # not another automatic conversion, this time number/string
$course +=2;                    # $course is now 246

2.2.2 Arrays

Perl can group a number of scalars together in an array. The entire array can be referenced as a single variable or one can access one element of the array. In Perl, arrays are denoted by the "at" character (@). Each array can contain any number of elements, which are simply scalars. Arrays can be assigned to and from lists, denoted by parantheses:

$c1 = "white";
$c2 = "black";
$int1 = 100;
@colors = ("red","green","blue");
@otherarray = ("yellow",$c1,$c2,$int1);
($first,$second,$third,$fourth,$fifth) = @colors;

Like scalars, arrays can be printed and interpolated into strings. Note that as in our example above, an array need not contain scalars of the same type. This is useful when we interpolate one array into another, operation that inserts each of the elements of an array into another array:

@newcolors = ("white",@colors,$c2,$int1); # @newarray contains ("white","red","green","blue","black",100)

Individual elements of an arrray can be accessed by their indices, which as in C, normally starts at zero. Since the elements of an array are scalars, when we reference to them we use the "dollar" character ($) and not the "at" character (@). Thus

print "First color is $newcolors[0].";

will print "First color is white.". The highest index (the one which specifies the last element) of the @colors array is given by $#colors, while the size of the array (generally one larger) is the scalar value of the array. One can use these variable backwards, to set the size of an array. For example:

$lastcolor = $colors[$#colors];    # $lastcolor is now "blue"
$lastsize = @colors;               # $lastsize is 3
$#colors = 1;                      # @colors is now ("red","blue)

Perl provides enormous built-in support for arrays, making them very handy data types. We are just touching the water here. You will see later that Perl provides all the necessary functions to manipulate array content very easy and convenient. Another Perl interesting feature is that return values are not limited to scalars. Functions may also return an array.

Multidimensional arrays are declared as lists of lists (or arrays of arrays). When declared, each row should be enclosed in square brackets.

@matrix = ( [1,2,5],
            [2,4,7],
            [9,2,8]);

To access one of the elements we use the following notations, which are equivalent:

print "Row 2 Column 1 is $matrix[1][0].";
print "Row 1 Column 1 is $matrix[0]->[0].";

Furthermore, Perl is even nicer than that. We can have an array in which some of the elements are scalars and some of them are arrays! For example:

@record = ("John",["3.6","3.2","3,4"],
           "Mark",["3.9","3.8"]);
$print "In the first year of college $record[0]'s GPA was $record[1]->[0].\n";
$print "In the second year of college $record[2]'s GPA was $record[3]->[1].\n";

will print

In the first year of college John's GPA was 3.6.
In the second year of college Mark's GPA was 3.8.

2.2.3 Associative Arrays

Associative arrays are like normal arrays. However, instead of being indexed by numbers, they are indexed by strings. So, while in a standard array you can look just for entry like 1, 2, 3,..., in associative arrays you can use "3.1415927", "pi" or even "Look ma', I found my entry!" as indices. You, a C programmer, may wonder "What's the use of it?" while Perl programers wonder "How can C programmer live without it?". This is the main tool for a CGI program to read the data from the user. As scalars and standard arrays, associative arrays are indicated by a special chracter, in this case the percent sign (%). And, as with standard arrays, each element can be a scalar or ... another associative array. However, in order to differentiate elements of an associative array from those of normal ones, we use curly braces rather than square brackets. Note that we can have a scalar, associative array and standard array using the same name. The only thing that differentiate them is the leading sign before the variable name. Thus

$variable = 1;
@variable = (3,"English","French");
%variable = ('red','Rouge',
             'black','noire',
             'hello','bonjour');
$variable{'blue'}="Bleu";
print "$variable{'red'} means red in $variable[$variable+1]!\n";
print "$variable{'blue'} uses the same characters in $variable[1] and $variable[2].\n";

Can you predict the output of the above program?

Thus, there are two ways to assign values to an associative array. One is to list all the element. Remember that if you are using this method, you have to list pairs of values, one for the key (or index) and one for the value (or the scalar that you want to access by using the key). Thus we have to have an even number of entryes. The other method is to assign the values one by one.

$variable{'bread'}="pain";

When we have multidimensional associative arrays, we have to use the "->" sign to access them. For example

%pers_record = ('Bogdan'=>{'Address'=>'C1605','Phone'=>'x7869','College'=>'BMC'},
             'Walt'=>{'Phone'=>'x7483','College'=>'BMC','Room'=>'Park 360'});
print "Bogdan's phone extension is $pers_record{'Bogdan'}->{'Phone'}.\n";
print "Walt's room is $pers_record{'Walt'}->{Room}.\n";

will print

Bogdan's phone extension is x7869.
Walt's room is Park 360.

Note that in the example above, we used => to separate the key from the value. You have to use this in multidimmensional associative arrays. Also note that inside the paranthesys, we used curly braces. You can pass values between standard arrays and associative arrays.

%assoc = {'Bogdan'=>'CS246','Deepak'=>'CS110'};
@standard = %assoc;      # @standard becomes ("Bogdan","CS246","Deepak","CS110");
@news = ("Deepak2","CS380",@standard);
%assoc = @news;
print "Prof. Kumar teaches $assoc{'Deepak'} and $assoc{'Deepak2'}.\n";

will print

Prof. Kumar teaches CS110 and CS380.

The associative arrays are also used to access and use system and HTTPd variables.

2.2.4 Special variables

There are two important variables in Perl @_ and $_. The first one is used mainly to transfer parameters to functions. In Perl, the parameters passed into a function do not have any special names. They neither need to be declared in advance, nor must they be specified as part of the function definition. Instead, the special array @_ holds all of the parameters that are passed into a function. Each parameter can be accessed by its zero-based index; that is, the order in which it was passed to the funtion. Thus the first parameter would be $_[0], and the fifth one would be $_[4]. Since these name are pretty confusing, it is better to use an array-to-list transfer so our variables will get the right value. For example, if we have a function called add which will add two numbers and then print the result, we will call it by

&add(11,25);

and the function may look like

sub add
{
   ($number1,$number2)=@_;
   $result=$number1+$number2;
   print "$number1 + $number2 = $result\n";
}

The second special variable, $_, is used by some Perl functions which operate onto it. We will discuss later about these function.

2.2.5 Local vs. Global Variables

In Perl, all variables are global. Thus, if we have a variable called $name in the MAIN block and we want to declare onother one with the same name in one of our functions, we have to declare it local. In order to do so, at the first time we use the variable in the function, we have to use the following sintax

local $name = 0;

or no matter what value we want to assign to our variable. The local keyword will make sure that we will not erase the content of the global variable while we are using this variable inside the function. We do have to declare it local in each block (function) where we do not want to affect the content of the main variable.

2.3 Conditional Statements and Loops

Note: When we are using numerical relationships to build conditions for loops and conditional statements, (e.g., 1 + 1 = = 2) we have to use one of the following simbols = =, !=, <, <=, >=, >. For string relationships, we use eq, ne, lt, le, ge, gt. The AND (&&) and OR (||) operators are used exactely as in C to combine conditional expressions.

2.3.1 WHILE

The while statement executes the block as long as the control expression after the while is true. An expression is true if it evaluates to non-zero.

while ($string ne "done") {
   ....
}

2.3.2 UNTIL

The until statement executes the block as long as the control expression after the until is false or zero. When the expression evaluates to true (non-zero), the loop exits.

until ($string eq "done") {
   ....
}

2.3.3 IF

The if stateme looks pretty much like its C correspondent.

if ( condition ) {
   ....
   ....
}
if ( condition) {
   ....
} else {
   ....
}
if ( condition ) {
   ....
} elseif {
   ....
   ....
} else {
   ....
}

2.3.4 UNLESS

The unless statement is similar to the if statement, except that the control expression after unless is tested for the reverse condition, that is, if the conditional expression following the unless is false, this statement is executed.

unless ( condition ) {
   ....
   ....
}
unless ( condition) {
   ....
} else {
   ....
}
unless ( condition ) {
   ....
} elseif {
   ....
   ....
} else {
   ....
}

2.3.5 FOR

The for loops looks the same with its C correspondent.

for ($i=10;$i<100;$i++){
   ....
}

2.3.6 FOREACH

The foreach loop iterates over each element inthe paranthesized list (an array), assigning each element of the array to a scalar variable, one after the other, until the list is empty.

foreach $pal ("Tom","Harry","Pete") {
   print "Hi $pal!\n";
}

2.4 Designing a Form for your Perl Program

To input data to your CGI program (be it C or Perl) you have to design a html page which will be the user interface for your porgram. When you are designing such a page, there are a number of HTML tags that you can (and have to) use. First we have to specify the CGI program that will process the data from this form and the method in which the data will be sent to it. For now we will use the GET method. Later we will study other methods and will discuss the differences between them.

<form action="http://mainline.brynmawr.edu/cgi-bin/bbutoi/cs246/example1.perl" method=GET>

Note that the CGI program is called by the complete URL. You can use also a partial URL if it stays on the same server with the page that contains the form. Now, that we specified the program, we have to define the input fields. Each input field is like a variable. We define its type, name and value. Some of them have more attributes that we can use to better format the entry form. For example

Enter your name<br>
<input type="text" name="yourname" size=50><br>

will create a text field which can accomodate a string of 50 characters. We will indentify this field in our program by its name, i.e. yourname.
We use radio buttons to create a set of options from which the user should use only one. For this we create more than one input sharing the same name. The variable will have the value corresponding to the selected input item.

<input type="radio" name="country" value="France">I'd like to go to France<br>
<input type="radio" name="country" value="England">I'd like to go to England<br>
<input type="radio" name="country" value="Germany">I'd like to go to Germany<br>

A checkbox field will assign the value to its variable if it is checked or nothing if it is not checked. More than one checkbox fields can use the same variable name. The final value stored by that variable will be obtained by adding (concatenating) all the values of the marked fields. One can use the CHECKED attribute to specify that the initial status of the field shoul be "checked".

<input type="checkbox" name="option" value="on" CHECKED>Sound (on|off)<br>
<input type="checkbox" name="SRS" value="srson">SRS (on|off)<br>

A password field is like a text field but the text entered by the user is not displayed.
A hidden field is used to store some variables for the CGI program that can not be edited by the user.
A image field will display the image pointed by the src attribute.

The last two important types are sumbit and reset. They no not have a name. These are the buttons that will start the CGI program

<input type="submit" value="Press here to start the CGI program">

or to clear the form

<input type="reset" value="Clear this form">

And, at the end, we have to close the form definition

</form>
Look here to see how the above example looks like.

2.5 Reading Parameters from a HTML Form

The parameters designed in the html form are passed as row data to the CGI program. There, we have to decode them in order to use them. For this we will use one of the functions included in the cgi-bin.pl library. First, we have to call the library. For this, we have to start our Perl program as follows

#!/usr/local/bin/perl
require "/export/home/http/cgi-bin/cgi-lib.pl";

Now that the library is included, we can call our function. To access a function, we have to use the the & sign before the name of the function. Therefore

&MyFunction;

will call the function MyFunction. The function that we need to decode the input from the html form is called ReadParse. This function will translate the input to the associatuve array in. To access the data from a field called title in our html form, all we have to do is to use the name as the index in the in associative array. Hence

&ReadParse;
print "The title is $in{title}\n";

will print the string The title is followed by the content of the title field from our form.

2.6 The First CGI Perl program

The following is a basic example for an HTML document that calls example1.perl.

<html>
<head><title>Form entry for example1.perl</title></head>
<body bgcolor=#ffffff>
<h1>Form entry for example1.perl</h1>
<form action="http://mainline.brynmawr.edu/cgi-bin/bbutoi/cs246/example1.perl" method=GET>
Enter your name:<br>
<input type="text" size=50 name="name"><p>
Enter your graduation year (ex. 1999):<br>
<input type="text" size=4 name="year"><p>
Enter your college:<br>
<input type="text" size=16 name="college"><p>
<input type=submit value="Send">
<input type=reset value="Clear">
</form>
</body>
</html>

This form will send the data to the example1.perl program, listed below.

#!/usr/local/bin/perl
require "/export/home/http/cgi-bin/cgi-lib.pl";
MAIN:
{
  &ReadParse;
  print "Content-type: text/html\n\n";
  print <<"EX1-T1";
  <html>
  <head><title>Results from example1.perl</title></head>
  <body bgcolor=#ffffff>
  <h1>Results from example1.perl</h1>
  Your name is $in{name}.<br>
  You are a student at $in{college}.<br>
  You will graduate in $in{year}.<br>
  </body>
  </html>
EX1-T1
}

Note: The tag used to mark the end of the text to be printed (which is EX1-T1 in our example) should be at the beginning of the line with no spaces before or after it.

Click to see how this page looks like and how it work with the Perl program.