Chapter 5: Introducing Perl

Functions, libraries, extensibility


[ Comments ] [ Copyright ] [ Chapter contents ] [ Book contents ]


No programming language is complete without the ability to define extensions such as user-specified functions. Arguably, it also helps to be able to bundle up frequently-used extensions into a library file that can be loaded on demand. Perl is fairly unexceptional in that it provides these facilities (and a little bit more besides).

You can define a subroutine in Perl quite easily:


sub myfunc { 
   local ($arg1, $arg2) = @_; 
   local ($result); 
   # 
   # do something or other with $arg1 and $arg2 
   # then place the results in $result 
   # return $result; 
}

This declares &myfunc, a user subroutine.

&myfunc makes use of two arguments; these are passed to it in the array @_, which is allocated locally when &myfunc is called. (There might be more than two arguments, in which case the extra ones are discarded.)

The function local() takes a variable as its parameter and makes a copy of it locally -- that is, $arg1, $arg2, and $result are local to &myfunc, and are expunged when &myfunc finishes.

Finally, after doing something with the arguments, a result is assigned to the local variable $result. The return command returns the value of its parameter; so when &myfunc finishes, it returns whatever was in $result:

$answer = &myfunc("1","2");

Note that in Perl, variables are global by default, and must be specifically identified as local if you want their scope to be restricted. This is the opposite behaviour to languages like Pascal or, to a lesser extent, C. It is less of an issue in Perl 5, which can handle persistent, encapsulated data objects.

The reason for the odd variable scope rule takes some explaining. Perl keeps all its variables in a central symbol table (called main). When you define a variable within a subroutine as being local, a local symbol table is created; thus, references outside that subroutine don't see an entry for a variable of that name in the main symbol table.

Perl can load libraries of external functions by using the require statement. require "filename" makes Perl load and interpret "filename" as a sequence of Perl commands. If the commands are preceded by a package declaration, like: package myfuncs;

a new symbol table is created (called myfuncs). You can refer (within the scope of main) to symbols in myfuncs by using a quote-mark ' to qualify the reference.

For example, suppose we have a file called otherstuff.pl, that contains a package called otherstuff:


# otherstuff.pl
#

package otherstuff;
@myarray = ("sweet","sour","salty");

1;
#
# note that all packages must return "1" when exiting

Now let's create a program that loads the package otherstuff and does something with it:
# main program
# define an array, @myarray

@myarray = ("red","green","blue");

#let's load package otherstuff from file otherstuff.pl
#

require "otherstuff.pl";

#
# now let's print the contents of the array @myarray, 
# first in the scope of the main symbol table, then 
# in the scope of otherstuff;

foreach $thing (@mystuff) {	# main symbol table
	print "$thing\n";
}

foreach $thing (@otherstuff'mystuff) {	# otherstuff
	print "$thing\n";
}

This will result in the output:

redgreenbluesweetsoursalty

If a variable is defined in a package, you can refer to it in the main program by specifying the package name. This makes Perl check the package's symbol table rather than the main one. Subroutines with local variables also have symbol tables, and you can access them from the main program (and vice versa).

If you don't add a symbol table's specifier in front of a variable name, the main symbol table is assumed; so $fred is identical to $main'fred.

A large number of packages are available to Perl users; many of them are specifically designed for the World Wide Web.

First and foremost, for serious work on the web it is useful to get hold of a copy of libwww-perl. This library (which can be obtained from http://www.ics.uci.edu/) provides an extensive set of tools for handling HTTP queries and parsing HREF tags.

This library enables you to do things like:

While it's not essential for writing CGI scripts, it comes in very useful in advanced work (such as that described in "Writing a web structure viewer").

It's also useful to have a library to hand for handling CGI stuff; notably for getting requests, decoding them, and giving access to the variables in them through an associative array. (Routines for doing this are included later in this chapter. Alternatively, check http://www.yahoo.com/text/Computers_and_Internet/Internet/World_Wide_Web/CGI___Common_Gateway_Interface/ for the latest popular ones.)

If you are willing to learn, it may be worth looking into Perl 5. While there is still a shortage of tutorial texts on this language, Perl 5 is strictly speaking a superset of Perl 4; the most significant addition is object orientation. Various object libraries are available, including:
CGI.pmLibrary for creating forms and handling CGI queries. Includes "persistence" -- you can reload a form and view the state of a query at a later date.
GD.pmLibrary for creating GIF images "on the fly". Using GD (which requires some external compiled code) you can specify arcs, lines, fill regions, and colours, then output a GIF containing a diagram composed to your specifications.
HTML.pmA library for generating HTML programatically. This is most useful in conjunction with a database library, for automatically producing the HTML text around a database report.
DBI.pmA library for interfacing to databases. Currently supports a range of databases including mSQL (a popular free SQL database), Oracle, Informix, and most of the heavyweight commercial SQL databases. You can compose queries in SQL, and receive the results in a neatly formatted perl array (which you can then print using HTML.pm).


To learn about Perl 5, the best starting point is the usenet newsgroup comp.lang.perl.announce. FAQ (frequently asked question) files are posted there on a weekly basis. These include a list of all available Perl 5 modules, and their current status. You can also find more information about Perl, and pointers to Perl information, on http://www.perl.com/. Once you have read the FAQs, you can read the newsgroups comp.infosystems.www.authoring.cgi (general CGI-related questions -- a FAQ is also posted there, every week) and comp.lang.perl.misc (miscellaneous Perl-related discussion).

Be advised that, before you even think about posting a question, it's a good idea to read the FAQ; FAQs contain the most frequently asked questions and their answers, and there's a good chance that someone has asked the question before you. (Asking a question which is answered in the FAQ is a good way to get shouted at.)


[ Comments ] [ Copyright ] [ Chapter contents ] [ Book contents ]