Vous êtes sur la page 1sur 27

Perl

PERL
Perl stards for Practical Extraction and Reporting Language. The man pages describe it best.
"Perl is a language optimized for scanning arbitrary text files, extracting information from those text files, and printing reports
based on that information. It's also a good language for many system management tasks. The language is intended to be
practical (easy to use, efficient, complete) rather than beautiful (tiny, elegant, minimal).
Perl combines (in the author's opinion, anyway) some of the best features of C, sed, awk, and sh, so people familiar with those
languages should have little difficulty with it. (Language historians will also note some vestiges of csh, Pascal, and even
BASIC-PLUS.) Expression syntax corresponds quite closely to C expression syntax. Unlike most Unix utilities, Perl does not
arbitrarily limit the size of your data--if you've got the memory, Perl can slurp in your whole file as a single string. Recursion
is of unlimited depth. And the tables used by hashes (sometimes called "associative arrays") grow as necessary to prevent
degraded performance. Perl can use sophisticated pattern matching techniques to scan large amounts of data very quickly.
Although optimized for scanning text, Perl can also deal with binary data, and can make dbm files look like hashes. Setuid Perl
scripts are safer than C programs through a dataflow tracing mechanism which prevents many stupid security holes.
If you have a problem that would ordinarily use sed or awk or sh, but it exceeds their capabilities or must run a little faster, and
you don't want translators to turn your sed and awk scripts into Perl scripts. "
--man perl

Let's not waste any more time flapping our gums. It's code'n time!
We tested everything out on a system using Redhat 6.0 with Kernel 2.2.5-15. The Web server was Apache 1.3.6 with the Perl
modules all set up.
The first thing we'd like you to do is create a directory called /pjunk. Create it anywhere you want, it's just something to hold
the junk code you'll be writing. Yup! you'll be churning out proper tripe before the day's out!
Now start up the browser of your choice and type in 127.0.0.1 or localhost or localhost.localdomain. All of them point to the
same location, your own machine.
When you now press Enter, your browser will connect to the Web Server, in this case Apache, running on your local machine
and will ask for the default file. This file resides in /home/httpd/html (or whatever directory you set as the root directory when
you installed Apache) and is named index.html. Apache picks up this file and sends it to your browser, which then displays it,
informing all and sundry that 'It Worked!'.
Start up a terminal window and 'cd' your way to this directory. Use your favorite text editor to make a file 'a.pl' and save it to
this directory.
a.pl
print Content-Type:text/html

http://www.vijaymukhi.com/documents/tutorials/perl.html (1 of 27) [2003-01-24 9:55:09 PM]

Perl

Now go back to the browser and type in '127.0.0.1/a.pl', press Enter and what do you see? the contents of the file a.pl listed on
your screen.
This isn't exactly what we had in mind. We want the Perl program a.pl to execute when type it's name in, not have it displayed
by Netscape!
It seems that if you place your Perl program in any old directory, Apache will treat it as a normal text file. When asked for it, it
will pick it up and shoot it across to your browser, without trying to run it or do anything at all with it.
Let's try a.pl out with Perl.
bash# perl a.pl
syntax error at a.pl Line 1, near "Type:"
Execution of a.pl aborted due to compilation errors.
No good. It barfs all over us.
Let's try this
bash# ./a.pl
bash: ./a.pl: Permission denied
It refuses to run. This we can solve.
bash# ls -l a.pl
-rw-r--r-- 1 root root 46 Sep 7 18:03 a.pl

The r, w and -'s on the extreme left are file permissions. Everyone on a UNIX system belongs to three groups viz a viz a file.
You are either it's creator, or you belong to a relevant group or you're a total outsider. The - on the extreme left tells you about
the nature of the file, the three characters after that explain what the owner of the file can do with it. He can either (r)ead from
it, (w)rite to it or e(x)ecute it. In the same way, the next three characters show what a person belonging to the same group as
the owner can do with the file and the last three characters show what everyone on the system can do with the file.
In this case, the owner can read from and write to his file and everyone else can read from it. However, no one has execute
permission. Let's remedy that.
bash# chmod +x a.pl
bash# ls -l a.pl
-rwxr-xr-x 1 root root 46 Sep 7 18:03 a.pl
Now everyone has permission to execute this file. Let's do just that.
bash# ./a.pl
./a.pl: print: command not found
This looks suspicious. What's happening here is that instead of Perl running the file and spitting out an error, our shell BASH
assumes that this is a shell script and attempts to run it. Since it isn't, BASH trips over its own feet and prints an error.

http://www.vijaymukhi.com/documents/tutorials/perl.html (2 of 27) [2003-01-24 9:55:09 PM]

Perl

What we need to do is tell BASH to run Perl when we try to execute a.pl. We do that by modifying a.pl as shown below.
a.pl
#!/usr/bin/perl
print Content-Type:text/html
In a shell script, a '#' is usually used to mark a comment. But when it's followed by a '!', it's an instruction to the shell telling it
to run the program specified and to pass the contents of the file to it.
bash# ./a.pl
syntax error at a.pl Line 1, near "Type:"
Execution of a.pl aborted due to compilation errors.
Ah yes, a familiar error message. It seems that Perl is being called now.
Things still don't work though, but we'll get to that in a moment
copy this file to /home/cgi-bin/ and get back to your browser. Type in
127.0.0.1/cgi-bin/a.pl and press Enter.

Apache reads your trashy code, giggles wildly, slams you with an Internal Server Error and then politely tells you to contact
the server admin.
Apache isn't crass enough to scream to all the world that you don't know how to program using Perl. It receives an error
message from Perl and so it sends a polite error page across.
Change a.pl to look like this.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html"
All we need to do is add the "'s and it works! The output if we run it from the shell is
bash# ./a.pl
Content-Type:text/htmlbash#
Perl demands that all strings be surrounded by ""'s. There's no arguing with it. It's syntax.
Now let's reload this file from the browser. No luck, Apache still isn't satisfied so we must be doing something wrong.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n"
Save the file and reload the page in the browser. We're still getting an error, but it's a different one this time. Netscape tells us
that the 'document contains no data' and would we try again later?

http://www.vijaymukhi.com/documents/tutorials/perl.html (3 of 27) [2003-01-24 9:55:09 PM]

Perl

The reason we get this error is because Netscape expects every HTML page to contain data. A proper HTML page is made up
of two sections, the header and the actual data. Our Perl program just sends a single line of the header (containing the MIME
type) across. This line tells the receiving browser that the data to follow is of type text/html and to treat it as such. When
Netscape receives nothing after the header, it suspiciously flags an error and shows a warning message box. If you try this with
a more laid back browser like Lynx, you're shown a blank page and nothing more.
The two '\n's tell the browser that the headers have ended.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n"
print "hi"
Type in the new line and test the program at the prompt
bash# ./a.pl
syntax error at ./a.pl line 3, near "print"
Execution of ./a.pl aborted due to compilation errors
This error is rather easy to get rid of. It's another syntaxical gaffe of ours. All lines must end with a ';' in Perl, except the very
last one. That's why our one line program worked without a semi-colon. Just add the missing semi-colon.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
print "hi"
Now the program will work just fine, from both the shell and the browser.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
print "hi ";
print "bye";

As far as the semi-colon issue goes, we'll just stick to putting them after all our statements, a la C.
This program goes one step further than the earlier one by having two print statements instead of one. You'd expect the
plesantries to appear on two lines, but on both your browser and the shell, they'll be squashed together on one.
Let's try this out.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
print "hi\n";
print "bye";
http://www.vijaymukhi.com/documents/tutorials/perl.html (4 of 27) [2003-01-24 9:55:09 PM]

Perl

Getting warm now. When run as a Perl script from the shell, the output is separated by a newline, but you'll still see the two
words on the same line in your browser.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
print "hi<p>";
print "bye";
Now this is the exact opposite. Under the shell, you're simply shown the contents of the print statements on a single line. As
displayed by your browser however, they will appear on two distinct lines.
Just one more to drum the point in.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
print "<h1>hi</h1>";
print "bye";
Now the 'hi' will be shown in a larger font on your browser.
All this goes to show that you can put any HTML tag in the print statement and when seen through the eyes of a browser, they
will be interpreted and accepted as such. What we're doing through these simple programs is actually _constructing_ Web
pages on the fly. A more complicated version of this happens when you go to any search engine. The page with your results on
it is created on the server by a program, and then sent across to you. You can also grab a file off the disk and shoot it across,
but we'll deal with that a little later.
Now lets delve a little deeper into the innards of Perl. Try this.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
print "hi $i bye";
You'd expect to be shown the string 'hi $i bye' but you'll get 'hi bye' instead.
Anything in Perl that starts with a '$' is special. It's a variable. A variable is an entity that can hold a single, changeable value.
But to use a variable you have to \idefine\i it first and we haven't done that yet. Since this variable has no assigned value, Perl
simply gives it a Null value which means it has no value at all. Unlike other programming languages, Perl doesn't start spitting
out errors when it finds variables floating in mid air, as it were. It just tries to guess the right response and move along with the
flow.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
$i = "hi bye";
print $i;
Here we've give '$i' a value. In tech-speak, we've \ideclared\i and \idefined\i a variable. In Perl both steps are carried out at the
http://www.vijaymukhi.com/documents/tutorials/perl.html (5 of 27) [2003-01-24 9:55:09 PM]

Perl

same time.
So this little script will print 'hi bye' at both the shell and through the browser.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
$i = "hi bye";
print $i;
$i = "bye";
print $i;
$i = 100;
print $i;
This is a fairly simple program that demonstrates that a variable's value is, well, variable. We can change it to anything we
like.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
$i = 100;
print "$i <p>";
$i = $i + 7;
print "$i <p>";
$i = $i + 1;
print "$i <p>";
$i++;
print "$i <p>";
Here's proof that Perl can do math. We first assign '$i' the value 100, print it out (remember, the value of the variable will be
printed out, not the string '$i'). Then we add '7' to the current value of '$i', making it 107. We then add '1' making it 108 and
finally we do a '$i++' which is simply shorthand for the longer '$i = $i + 1'. The final print prints out 109.
So much for variables. On to more substantial fare.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
if (1)
{
print "True<p>";
}
if (0)
{
print "False<p>";
}
Control statements add intelligence to your programs and give them the ability to make decisions. The IF statement is one of
the most important and basic control statements to be found in any programming language.
In the third line of the program we say
http://www.vijaymukhi.com/documents/tutorials/perl.html (6 of 27) [2003-01-24 9:55:09 PM]

Perl

if (1)
{
print "True<p>";
}
The value that IF is to test is always in ()'s. In this case it's the number '1' which when used in any decision making statement
means TRUE. The pair of {}'s are also compulsory as dictated by the syntax rules. All statements to be executed if the IF
statement is found to be TRUE are enclosed within. In this case, all we have is a single print statement.
The second IF statement is identical in structure, except that it test the number '0' which is always FALSE. If, some how, '0' is
found to be TRUE, the print statement would churn out 'False'.
Try it out.
You just get to see the True.
That's because only if the result of the IF statement is TRUE will the statements within the {}'s be executed. '0' (which is
_always_ FALSE) is never going to equal TRUE, so the contents of the second IF statement are never executed.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
if (4 > 8)
{
print "4 > 8 is never true<p>";
}
if (4 < 8)
{
print "4 < 8 is always true<p>";
}
Here's another one in a similar vein to clear things up. Only the contents of the second IF statement will be executed. That's
because the number '4' will _never_ be larger than '8'; it's always smaller and that's why the second IF statement is executed.
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
if (4 > 8)
{
print "4 > 8 is never true<p>";
}
else
{
print "the else<p>";
}
Instead of using two IF's we can use an ELSE. If the IF statement is not TRUE (as it isn't in this case), the ELSE will be
executed. It's just like a statement of fact in English. "If this is true, do it, or else do this".
a.pl
#!/usr/bin/perl
http://www.vijaymukhi.com/documents/tutorials/perl.html (7 of 27) [2003-01-24 9:55:09 PM]

Perl

print "Content-Type:text/html\n\n";
while ($i <= 10)
{
print "$i <p>";
$i++;
}
Here we have another control statement, the WHILE. WHILE repeats a set of statements (enclosed in {}'s) while the condition
within it's ()'s is TRUE.
So while '$i' is less than or equal to '10', the statements will be executed, otherwise not.
In this case '$i' is automatically give a value of '1' instead of a blank value (a Null) because Perl is smart enough to notice that
you're using the variable in a mathematical context. Therefor it would make more sense if the value was a number.
So the WHILE will run while the value of '$i' is less than or equal to '10'.
The line
$i++;
is vital. If it isn't there then the value of '$i' would never increase and we'll be stuck in the WHILE statement forever! A
condition known as an Infinite Loop. Since we're incrementing the value however, the WHILE will run ten times and the
values of '$i' from one to ten will be printed out.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
for ($i = 2; $i <=10; $i++)
{
print "$i <p>";
}
A FOR statement is identical in use to a WHILE statement, though the syntax is a little different.
In the FOR, we first set the initial value of '$i' (we \iinitialise\i it) to '2'. After the semi-colon, we then set the condition i.e. the
statement should loop while '$i' is less than or equal to the number '10'. After the last semi-colon, we tell the FOR statement
what to do with '$i' after every iteration and in this case, we want to increment the value by '1'.
So the print statement prints out the numbers two to ten.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
$i = 30;
@a = (6 , "Hi", Bye , $i );
print @a;
print "@a";
Up till now, we've dealt with variables that start with a '$'; those that can only hold one value. Now let's check out those

http://www.vijaymukhi.com/documents/tutorials/perl.html (8 of 27) [2003-01-24 9:55:09 PM]

Perl

variables (called arrays in C and most other languages) that can hold multiple, usually related, values. These variables start
with an '@' sign and values are assigned to them in the manner shown above. We don't have to use ""'s to demarcate strings,
we can simply write out what we want ( as in the case of the string Bye). We can even have a variable as part of the array.
The first print will print out all the values, without any spaces so they appear joined together. The second print will display the
values with spaces in between them.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
$i = 30;
@a = (6 , "Hi", Bye , $i );
print "@a[0] , @a[20] , @a[2] , $a[2]";
The output in your browser will be
6,,Bye,Bye
This program shows another way to access the stores values. Look carefully at the print statement. Using '@a[0]' we tell the
Perl interpreter to access the _first_ (Perl in this case counts from zero onwards) member of the array. So '6' is displayed.
Similarly, we next ask for the twenty first (remember, we're counting from zero) member of the array, which hasn't been
defined. Perl doesn't complain. All it does is return a Null. Next, we ask for the third member, and Perl returns 'Bye'. Finally,
we demonstrate that we don't have to use '@' to access an array, the good ol' '$' sign will suffice. We get a 'Bye' here too.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
@a = (6 , "Hi", Bye , $i );
print "$#a <p>";
print "@a[0,2] <p>";
print "@a[0..2] <p>";
print "@a[$#a] <p>";
print "@a[-1] Last <p>";
The text displayed in the browser window is
3
6 Bye
6 Hi Bye
Last

Notice that we've removed the variable '$i' from the script. The first print will output the total number of members in the array
'@a'. That's what the '$#a' means. Next, we have '@a[0,2]', which means output the first and third members. '@a[0..2]' gives us
the members in the range zero to 2. So we get the string '6 Hi Bye'. The fourth print is supposed to give us the last member of
the array, but since that is a Null ('$i' is no loner initialized to anything), we get nothing. The final print does the same thing,
i.e. it accesses the last member of the array. Here too, we get a Null and the word Last.

http://www.vijaymukhi.com/documents/tutorials/perl.html (9 of 27) [2003-01-24 9:55:09 PM]

Perl

a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
@a = (6 , "Hi", Bye , $i );
foreach $aa (@a)
{
print "$aa <p>";
}
Here's a simple program that prints out all the members of the array '@a'. FOREACH is a reserved word. What happens here is
that each time through the loop, '$aa' is assigned the value of a member of '@a', from zero onwards. In other words, foreach
iteration of the loop, '@aa' holds the value of the next member in '@a'.
Here's another way to do it.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
@a = (6 , "Hi", Bye , $i );
for $aa (@a)
{
print "$aa <p>";
}
It's exactly the same when you use a simple FOR. It's up to you to decide what coding style you wish to follow.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
@a = (6 , "Hi", Bye , $i );
for $aa (0 .. $#a)
{
print "$aa $a[$p] <p>";
}
You should be able to guess what this program does just by looking at it. It's simply going over some old ground.
In the FOR loop, we're cycling through the range of values from zero to the last value of the array. Within the loop, we print
those values out.
Nothing to it.

a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
@a = (6 , "Hi", Bye , $i );
for (@a)
{
print "$_ <p>";
http://www.vijaymukhi.com/documents/tutorials/perl.html (10 of 27) [2003-01-24 9:55:09 PM]

Perl

}
Here's just a little bit of extra information. The variable $_ is a special one. It always holds the last value returned. It's like
saying 'print "$aa <p>" in the earlier programs. So here in the loop, the print statement will output a list of all the members in
'@a' as the FOR statement loops the loop.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
@a = (6 , "Hi", Bye , $i );
for (@a)
{
print ;
}
In fact, you don't need to use the '$_' at all. If you put nothing else after the print, Perl will automatically add the '$_' internally
and everything will work as before.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
%a = ("a1","b1","c1","d1");
print $a{"a1"};
print $a{"b1"};
print $a{"c1"};
In this program we introduce something new, a _third_ kind of variable! This one's called a 'hash' or a 'hash table' or even an
'associated array' and it's made up of paired values. It's a lot like an array, except that here each member is either a \ikey\i or it's
associated \ivalue\i.
This new variable is marked with a '%' sign and the members are initialized as shown. Here, 'a1' is the key member and 'b1' is
the associated value. Similarly, 'c1' is the key and 'd1' is the value. They're written out one after the other as shown.
The print statement also has a slightly different format. There's no explaining it; it's syntax and we have to simply accept it as
such. The first print will display 'b1' because that's the value of the key 'a1'. Similarly, the last print will display 'd1'. The print
in the middle however, will display nothing at all, since 'b1' is a value and not a key. Only the value can be displayed when the
key is given, not vice-versa.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
%a = ("a1","b1","c1","d1");
($a,$b) = each (%a);
print "$a , $b <p>";
$a,$b = each (%a);
print "$a , $b <p>";
Here, in line number four, we're putting the first key into '$a' and it's value into '$b'. So '$a' will contain 'a1' and '$b' will
contain 'b1'. We print that out.
Next, we try the same thing without the ()'s. No go. We end up with '$a' equal to 'a1' (because we haven't changed it's value
http://www.vijaymukhi.com/documents/tutorials/perl.html (11 of 27) [2003-01-24 9:55:09 PM]

Perl

yet) and '$b' contains 'c1', the key. This is definitely not something we want. The lesson as always is, stick to the syntax!
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
%a = ("a1","b1","c1","d1");
while ( ($a,$b) = each (%a) )
{
print "$a , $b <p>";
}
This is a nice clean way to print out all the values. While the loop loops, '$a' and '$b' will keep being given the key and value
members respectively and those will be printed out. The loop ends when 'each' reaches the end of the hash table and returns a
FALSE.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
%a = ("a1","b1","c1","d1");
@b = keys(%a);
print "@b <p>";
@b = values(%a);
print "@b <p>";
Here's a straight forward program. The function 'keys()' extracts the names of all the keys in the hash table '%a' and the print
displays them. Similarly, the function 'values()' extracts all the values and the next print displays them.

a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
%a = ("a1","b1","c1","d1");
print %a;
This program outputs a line with the keys and values, one after the other. The values are not separated by spaces.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
%a = ("a1","b1","c1","d1");
print "%a";
This program (surprise!) outputs the text
%a
Nothing more.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
http://www.vijaymukhi.com/documents/tutorials/perl.html (12 of 27) [2003-01-24 9:55:09 PM]

Perl

print %ENV;
Check this program out. Quite a lot of text for just one simple line. These are the Environmental variables available to Perl.
The hash table %ENV is a special one and is automatically created by the Perl interpreter and is always available for instant
use. It contains a lot of information about the environment your script is running in and can be very useful.For now, just gape
at the output and be amazed.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
foreach $aa (%ENV)
{
print "$aa <p>";
}
This script cleans up the output a bit by inserting a paragraph break after every line of data. It's all beginning to make sense
now, isn't it? Look at the output carefully. You can discover the server you're running under, the document root, the IP address
of the machine that called you,
all at run time. Useful, this is.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
print $ENV{"QUERY_STRING"};
print $ENV{"HTTP_HOST"};
Flashback to the earlier script where we were talking about extracting individual values for every string in a hash table. That's
what we're doing here. The first key, 'QUERY_STRING' gives us nothing at all because no parameters have been passed to our
script and so this key is empty. The second key, 'HTTP_HOST' holds the address of the client and that's what the print
dutifully displays.
Let's try this out...
Create an HTML file with the following text in it and copy it to
/home/httpd/html/ and name it a.html
<HTML>
<FORM ACTION="http://127.0.0.1/cgi-bin/a.pl">
<INPUT TYPE=TEXT NAME=aa><P>
<INPUT TYPE=TEXT NAME=bb><P>
<INPUT TYPE=SUBMIT VALUE="click">
</FORM>
</HTML>
Edit our pal a.pl to look like this.
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
print $ENV{"QUERY_STRING"};
http://www.vijaymukhi.com/documents/tutorials/perl.html (13 of 27) [2003-01-24 9:55:09 PM]

Perl

Now load on Netscape and go to http://127.0.0.1/a.html. Enter any old rubbish in to the two text boxes on display and click the
button named 'click'. You're immediately presented with the output from our Perl script; the text of the 'QUERY_STRING'
sent to us by the browser. Examine it closely. If, like me, you typed 'aaa' into the first box and 'bbb' into the second one, you'll
get the following.
aa=aaa&bb=bbb
Simple it is, but it's also the heart and soul of CGI programming. What we have here are a list of the text boxes on our HTML
page and the data entered into them, separated by ampersands. This is exactly the technique that sites like Yahoo
(www.yahoo.com) use. You enter text into their "Search" text box and the data is passed to a waiting script/program in the
server which examines the string and does the needful.
Of course, this string is pretty useless until it can be properly formatted and this is where Perl really shines. Sure, a language
like C would be faster, but C just can't handle strings as easily as Perl can. Perl is justifiably famous as one of the best scripting
languages around for text handling and not without reason. The next script shows just how easy it is to handle strings in Perl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
$a = $ENV{"QUERY_STRING"};
@b = split('=' , $a);
print "@b <p>";
foreach $i (@b)
{
print "$i <p>";
}
What this script does is cut up the 'QUERY_STRING' into members of the array '@b', at the '=' signs. So we end up with 3
members in '@b', "aa" "aaa&bb" and "bbb". Not exactly what we wanted, but we're getting there. Let's try chopping them up at
the '&'.
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
$a = $ENV{"QUERY_STRING"};
@b = split('&' , $a);
print "@b <p>";
foreach $i (@b)
{
print "$i <p>";
}
Just one character has been changed. The '=' in split() has been replaced by a '&'. We get
aa=bbb
and
bb=bbb
in the second and third lines respectively. This is definitely more useful. The next script should clear up any lingering doubts.

http://www.vijaymukhi.com/documents/tutorials/perl.html (14 of 27) [2003-01-24 9:55:09 PM]

Perl

#!/usr/bin/perl
print "Content-Type:text/html\n\n";
$a = $ENV{"QUERY_STRING"};
@b = split('&' , $a);
print "@b <p>";
foreach $i (@b)
{
print "$i <p>";
}
foreach $j (@b)
{
@c = split('=' , $j);
foreach $k (@c)
{
print "$k <p>";
}
}
This may look convoluted, but it's actually quite simple. Up until line number 8, everything is familiar. After that, we take the
array '@b' which has already been split at the '&' and further splice it at the '='. The inner loop just prints everything out.
Nothing to it really; and we get just what we want, all the keys and their values nicely lined up on after another with no
intervening ampersands and equal to's.
Onwards now to something a little overdue. Reading from a file. You should be able to decipher this yourself.
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
open(aa,"a10.txt");
while ($i = <aa>)
{
print $i;
}
close(aa);
This is quite straight forward. We use the function 'open()' to open the file of our choice. 'aa' is the name of the \ifile handle\i (a
variable that is use by us to refer to the file). In the WHILE statement we loop till we reach the end of the file. FALSE will
then be returned and we'll exit out. With in the loop, we're simply printing out the file. Notice that 'aa' is surrounded by <>'s.
There's no rationalizing it; it's syntax.
The final statement is the function close() which as the name suggests, closes a file and cleans up after it.
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
&aa;
&aa;
print "END <p>";
sub aa()
{
print "hi<p>";
}
http://www.vijaymukhi.com/documents/tutorials/perl.html (15 of 27) [2003-01-24 9:55:09 PM]

Perl

Here we introduce a new concept. The Subroutine. A subroutine is a quick and easy way to call code that will be repeated in
the script. Here we wish to print out the line 'hi' twice. We could either use two print statements one after the other or create a
subroutine 'aa()' which prints out the string and call it twice. This example is quite trivial, so it may not make to much sense to
use subroutines here, but what if the subroutine was many hundreds of lines of code long. We'd be in trouble without
subroutines then!
Why the '&' before the sub name? You better than to ask! It's syntax of course and there's no explaining it.
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
$i = &aa;
print "$i <p>";
sub aa()
{
print "hi<p>";
}
This program returns a value, which is stored in '$i'. The return value is the last value that's returned in the subroutine. Here,
it's the return value of print (which is 1) which is returned.
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
$i = &aa;
print "$i <p>";
sub aa()
{
print "hi<p>";
21;
}
Now the return value will be 21. Simple isn't it? Return values are used to indicate errors or to return the value of a calculation;
that sort of thing. You've come across them before. For example, split() returns an array.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
&aa(1,2) , "\n";
sub aa()
{
print $_[0] ,"\n" ;
print $_[1] ,"\n" ;
}
This script is a continuation of the same theme, but it's a tad more involved. Here we're passing the subroutine '&aa' two
parameters. To access these parameters in the subroutine, we use '$_'. Use '$_[0]' for the first one and '$_[1]' for the next.
These variables are created for you automatically, by Perl.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
http://www.vijaymukhi.com/documents/tutorials/perl.html (16 of 27) [2003-01-24 9:55:09 PM]

Perl

&aa(1,2,3)
sub aa()
{
print @_ ,
foreach $_
{
print $_ ,
}
}

,"\n";

"\n";
(@_)
"\n";

Here we first print out the parameters in one long line using '@_' and we then print them out one by one in a foreach loop.'@_'
is an array containing the parameters and is created automatically.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
print &aa(),"\n";
sub aa()
{
6;
}
Here's another way to return a number and print out it's value.
a.pl
#!/usr/bin/perl
print "Content-Type:text/html\n\n";
print &aa(1,2,3,4) , "\n";
sub aa()
{
$s = 0;
foreach (@_)
{
$s += $_;
}
$s;
}
Here's a nice little program that puts everything together for us. We pass the subroutine four parameters. In the subroutine we
then initialize the variable '$s' to 0 and use it in the FOREACH loop to add up all the parameter values. FOREACH will loop
until all the parameters have been accessed and then it will end. Since we have '$s' as the last value in the subroutine that will
be returned as the return value and printed out.
MODULES
^^^^^^^
Up till now, all that we've done is create simple Perl scripts using the predefined functions in Perl. One of the things Perl is
justifiably famous for is it's extensibility. By that I don't mean hacking the Perl interpreter. True, it's source code is freely
available and if you want to you can do just about anything with it you want. Unfortunately, not too many people in the world
have the ability or the patience to go through some million lines of code just to add a new keyword or function!
http://www.vijaymukhi.com/documents/tutorials/perl.html (17 of 27) [2003-01-24 9:55:09 PM]

Perl

No, Perl, gives us a much simpler way to do what we want, modules.


Let's figure these beasts out.
x.pl
use Env;
print "Home: $HOME\n";
print "Name: $LOGNAME\n";
bash# perl x.pl
Home= /root
Name= root
Type in the script as shown into x.pl and then run the program using the perl interpreter. Notice that we're not using the '#!' to
call the interpreter, but doing it directly. It's no biggie, you can do things the old way if you want.
The output is shown above.
What this script does is use the module Env to automatically create some variables for our use. We then use these variables in
the print statements. Try the same program without the line 'use Env'. The print statements will only have blank lines after the
='s.
x.pl
use zzz;
bash# perl x.pl
Can't locate zzz.pm in @INC (@INC contains:
/usr/lib/perl5/5.00503/i386-linux /usr/lib/perl5/5.00503
/usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/perl5/site_perl/5.005
.) at x.pl line 1.
BEGIN failed--compilation aborted at x.pl line 1.

Let's try using a module of our own, which we'll call zzz. By putting the line 'use zzz' in the Perl script, we're telling Perl to
find and load the module into memory and to prepare it for use. Since we haven't yet gotten around to actually creating the
module file, Perl spits out a screen full of errors telling us it can't locate the file aaa.pm.

x.pl
use zzz;
zzz.pm
package zzz;
$x = 1;
bash# perl x.pl
<no output>

Right. Now we've created a file named zzz.pm and put the relevant lines into it. the word 'package' tell Perl the name of the
package and after that we create a variable and assign it a value. We get no output when we run the file, but no errors either.
http://www.vijaymukhi.com/documents/tutorials/perl.html (18 of 27) [2003-01-24 9:55:09 PM]

Perl

x.pl
use zzz;
zzz.pm
package zzz;
$x = 1;
print "hi \n";
bash# perl x.pl
hi
Okay, here's a line of output. Simple.
x.pl
use lib './';
use zzz;
zzz.pm
package zzz;
$x = 1;
print "hi \n";
bash# perl x.pl
hi
In this version of x.pl, we use the line 'use lib './'' precisely state the location of the module file. It could be anywhere on the
disk.
x.pl
use lib './';
use zzz;
zzz.pm
package zzz;
$x = 1;
sub xxx
{
print "Hi in xxx\n";
}
bash# perl x.pl
<no output>
We're going a little deeper now. We've created a small function name 'xxx' which prints out a line. Notice however, that when
we run the script, we get no output. That's pretty obvious to debug, we haven't called this new function from within x.pl!
x.pl
use lib './';
use zzz;
zzz::xxx();
zzz->xxx();
zzz.pm
package zzz;
$x = 1;
sub xxx
{
http://www.vijaymukhi.com/documents/tutorials/perl.html (19 of 27) [2003-01-24 9:55:09 PM]

Perl

print
}
bash#
Hi in
Hi in

"Hi in xxx\n";
perl x.pl
xxx
xxx

We've remedied that here and we get our output. We've actually called the same function twice, using two different styles.
They both mean the same thing, it's just a matter of personal preference which one you decide to use in the end.

x.pl
use lib './';
use zzz;
zzz::xxx();
zzz.pm
package zzz;
sub xxx
{
print "Hi in xxx\n";
}
bash# perl x.pl
zzz.pm did not return a true value at x.pl line 1.
BEGIN failed--compilation aborted at x.pl line 1.

Who would have thought that removing one simple variable. which we don't even use, would have given us an error. It seems
that our package must always exit out with an acceptable return value. So let's not quibble and give Perl what it wants.
x.pl
use lib './';
use zzz;
zzz::xxx();
zzz.pm
package zzz;
sub xxx
{
print "Hi in xxx\n";
}
1;
bash# perl x.pl
Hi in xxx
That's all that was required. A single return value.
x.pl
use lib './';
use zzz;
zzz::xxx();
zzz.pm
http://www.vijaymukhi.com/documents/tutorials/perl.html (20 of 27) [2003-01-24 9:55:09 PM]

Perl

package zzz;
BEGIN {print "start\n";}
sub xxx
{
print "Hi in xxx\n";
}
1;
bash# perl x.pl
start
Hi in xxx
The BEGIN is called a constructor and is the first thing called when you
say 'use zzz' in x.pl. It can be used by your script to initialize things
before any other function is called or variable is accessed.
x.pl
use lib './';
use zzz;
zzz::xxx();
zzz.pm
package zzz;
BEGIN {print "start\n";}
sub xxx
{
print "Hi in xxx\n";
}
END {print "over\n";}
1;
bash# perl x.pl
start
Hi in xxx
over
Similar in concept to the constructor, we have the destructor, END,
which is the last thing called before the module ends. It is supposed to
clean up after the rest of the module.

Of course, you needn't do all of this by hand. A nifty little program


named h2xs makes most of the framework automatically. Check it out below.
Try this out. Go to the directory of your choice, /pjunk for example and
type this in.

http://www.vijaymukhi.com/documents/tutorials/perl.html (21 of 27) [2003-01-24 9:55:09 PM]

Perl

bash# h2xs -A -n VMCI


You'll get these lines on your screen.
Writing
Writing
Writing
Writing
Writing
Writing

VMCI/VMCI.pm
VMCI/VMCI.xs
VMCI/Makefile.PL
VMCI/test.pl
VMCI/Changes
VMCI/MANIFEST

Now say
bash# ls -l
total 15
drwxr-xr-x 2 root root 1024 Sep 11 12:16 VMCI
Hmmm. We have a new directory named VMCI. Let's 'cd' into it.
bash# cd VMCI
bash# ls -l
total 6
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root
-rw-r--r-- 1 root

root
root
root
root
root
root

117 Sep 11 12:16 Changes


53 Sep 11 12:16 MANIFEST
369 Sep 11 12:16 Makefile.PL
1008 Sep 11 12:16 VMCI.pm
91 Sep 11 12:16 VMCI.xs
649 Sep 11 12:16 test.pl

Now lets edit the file VMCI.xs in a text editor. Use any you like.
VMCI.xs
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
MODULE = VMCI

PACKAGE = VMCI

This is the framework that h2xs automatically creates so that you don't have to type it in. Add the following lines to the file
after the line with MODULE = VMCI.
void
hello()
CODE:
printf("Hello\n");
This is the code of the function hello() that we wish to add have in our module.

http://www.vijaymukhi.com/documents/tutorials/perl.html (22 of 27) [2003-01-24 9:55:09 PM]

Perl

Now exit back to the shell and type in the following at the prompt.
bash# perl Makefile.PL
The following will be displayed.
Checking if your kit is complete...
Looks good
Writing Makefile for VMCI
Now type this in.
bash# make
This calls the resident C compiler which starts to compile the code.
mkdir blib
mkdir blib/lib
mkdir blib/arch
mkdir blib/arch/auto
mkdir blib/arch/auto/VMCI
mkdir blib/lib/auto
mkdir blib/lib/auto/VMCI
mkdir blib/man3
cp VMCI.pm blib/lib/VMCI.pm
AutoSplitting blib/lib/VMCI.pm (blib/lib/auto/VMCI)
/usr/bin/perl -I/usr/lib/perl5/5.00503/i386-linux -I/usr/lib/perl5/5.00503
/usr/lib/perl5/5.00503/ExtUtils/xsubpp -typemap
/usr/lib/perl5/5.00503/ExtUtils/typemap VMCI.xs >xstmp.c && mv xstmp.c VMCI.c
cc -c -Dbool=char -DHAS_BOOL -I/usr/local/include -O2 -DVERSION=\"0.01\" DXS_VERSION=\"0.01\" -fpic -I/usr/lib/perl5/5.00503/i386-linux/CORE VMCI.c
Running Mkbootstrap for VMCI ()
chmod 644 VMCI.bs
LD_RUN_PATH="" cc -o blib/arch/auto/VMCI/VMCI.so -shared -L/usr/local/lib VMCI.o
chmod 755 blib/arch/auto/VMCI/VMCI.so
cp VMCI.bs blib/arch/auto/VMCI/VMCI.bs
chmod 644 blib/arch/auto/VMCI/VMCI.bs
Manifying blib/man3/VMCI.3

Now type
bash# make install
to actually install the module. Notice where it's being copied.

Installing /usr/lib/perl5/site_perl/5.005/i386-linux/auto/VMCI/VMCI.so
Installing /usr/lib/perl5/site_perl/5.005/i386-linux/auto/VMCI/VMCI.bs
Files found in blib/arch --> Installing files in blib/lib into architecture dependend
http://www.vijaymukhi.com/documents/tutorials/perl.html (23 of 27) [2003-01-24 9:55:09 PM]

Perl

library tree!
Installing /usr/lib/perl5/man/man3/VMCI.3
Writing /usr/lib/perl5/site_perl/5.005/i386-linux/auto/VMCI/.packlist
Appending installation info to /usr/lib/perl5/5.00503/i386-linux/perllocal.pod

That's it! We're done. Now to test out the module. Create a file called
'hello.pl' containing the following Perl code.
hello.pl
#! /usr/bin/perl
use lib './blib' ;
use VMCI;
VMCI::hello();
Now run it from the prompt.
bash# perl hello.pl
Hello
It works! That's all there was to it. This is how we can extend Perl using modules written in C rather than Perl. So we can now
pretty much to whatever it is that C can do, in the warm and freindly confines of Perl.
Here is the .pm file that's automatically created for us. Notice the difference in size and complexity, yet it does pretty much
what we've been doing in a couple of lines.

package VMCI;
use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
require DynaLoader;
require AutoLoader;
@ISA = qw(Exporter DynaLoader);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
@EXPORT = qw(
);
$VERSION = '0.01';
bootstrap VMCI $VERSION;
# Preloaded methods go here.
# Autoload methods go after =cut, and are processed by the autosplit program.
1;
__END__
# Below is the stub of documentation for your module. You better edit it!
=head1 NAME
VMCI - Perl extension for blah blah blah
http://www.vijaymukhi.com/documents/tutorials/perl.html (24 of 27) [2003-01-24 9:55:09 PM]

Perl

=head1 SYNOPSIS
use VMCI;
blah blah blah
=head1 DESCRIPTION
Stub documentation for VMCI was created by h2xs. It looks like the author of the extension was negligent enough to leave the
stub unedited.
Blah blah blah.
=head1 AUTHOR
A. U. Thor, a.u.thor@a.galaxy.far.far.away
=head1 SEE ALSO
perl(1).
=cut

Now the implications of modules should be quite clear. Let's examine anexample of modules in action and how they can make
life easier for us. One of the many things Perl is used for in a Website is to accept registration forms and to add the information
to a database. Now, if we had to, we could have used a simple text file as the database and kept adding new data to it. That's a
clunky approach, but one we'd have had to adopt. The only other alternative would have been to write out own C modules that
would talk to a full commercial database like Oracle or Postgresql or MySql. Lots o' work, that!
But fear not! The tough stuff has already been done by someone else. Yes, ladies and gentlemen, there already exists a library
of modules, called the DBI (DataBase Interface) modules that can talk to almost every RDBMS in existence. You no longer
have to struggle with them yourselves, all you have to do is talk to DBI and it'll do the needful. Check out the following
programs.
a.pl
#!/usr/bin/perl
$host = " ";
use DBI;
$dbh = DBI->connect("DBI:mysql:test:$host");
$dbh->do("CREATE TABLE z5 (vno char(10))");
This is really simple. We first create a variable named '$host' and make it hold a space. In the next line we say 'use DBI' to use
the DBI modules.
We then call a function named 'connect' within the DBI module and pass it certain parameters. The first is the name of the
module itself, 'DBI'. The second is the name of the Database we wish to connect to. In our case it's 'mysql' because that's what
we're using. If you're using Oracle, you'd put that here. Everything else (and this is the crucial bit) would remain the _same_.
The third parameter is the name of the database we wish to use and the final one is the address of the machine on which the
RDBMS resides.We're passing it a space to tell DBI that MySql is on our machine, but you could put the address of any
machine you wished out here.
Connect will return a number which is the handle to this connection and this handle will be stored in the variable '$dbh'.
We then use the handle to call the function 'do' which is passed a string. This string (which in this case is an SQL statement) is
sent to the Database specified earlier. We're telling MySql to create a new table name 'z5' and make a single column in it, that
of 'vno' which is ten characters

http://www.vijaymukhi.com/documents/tutorials/perl.html (25 of 27) [2003-01-24 9:55:09 PM]

Perl

wide.
That's all that this program does.
a.pl
#!/usr/bin/perl
$t = "z5";
use DBI;
$dbh = DBI->connect("DBI:mysql:test");
$dbh->do("drop table if exists $t");
Here we connect to the SQL server as usual. Notice that we don't even need to give the host address if the server is on our
machine. We send the server the SQL command to drop the table if it exists. That done, we exit.
The only real reason we've done this script is to demonstrate that we can use Perl variables even within the strings to be sent to
the Database. The variables are replaced with their values before the string is shot off to the server.
a.pl
#!/usr/bin/perl
$t = "z5";
use DBI;
$dbh = DBI->connect("DBI:mysql:test");
$dbh->do("drop table $t") or die $DBI::errstr;
This program demonstrates the concept of error checks. If the table 'z5' cannot be dropped, then the program ends with the
error value displayed.
a.pl
#!/usr/bin/perl
use DBI;
$dbh = DBI->connect("DBI:mysql:test");
$sth = $dbh->prepare("select * from z5") or die $dbh->errstr;
$sth->execute() or die $sth->errstr;
$i=0;
while($row = $sth->fetchrow_arrayref)
{
print $row->[0] , "\n";
}
This program really puts things together. The first three lines are familiar by now. In the fourth line, we can a function named
'prepare' and give it the SQL command string as it's only parameter. This function doesn't send the string across, it simply
readies it for the trip. It returns a handle, which we store in the variable '$sth'. In the fifth line we use the handle to call the
function 'execute'. It's this function which 'executes' the SQL statement by sending it to the server.
In the while loop that follows, we use the function 'fetchrow_array' to retrieve the result, row by row and store it in '$row'. We
then print out values of the first (and in this case the only) column in the database.

http://www.vijaymukhi.com/documents/tutorials/perl.html (26 of 27) [2003-01-24 9:55:09 PM]

Perl

http://www.vijaymukhi.com/documents/tutorials/perl.html (27 of 27) [2003-01-24 9:55:09 PM]

Vous aimerez peut-être aussi