For the first script, you'll be given a sample form, and you'll need to do items 1-4 without the CGI.pm module. For the second script, you'll need to do items 1-5 with the CGI.pm module (we'll learn about CGI.pm tonight).
Since the lecture notes have complete scripts for doing the above tasks, you won't have to write your scripts from scratch. The best strategy will be to start with the scripts from the lectures notes, and then modify and extend them as needed to meet the requirements of the exam questions.
There will not be a lecture or lab after the midterm.
<FORM METHOD="GET" ACTION="/cgi-bin/your_script.pl">
#!perl
perl -c your_script.pl
Perl comes with a built-in library of functions. For example, when you use the print function, you are calling a function that is available in the Perl function library. Often, when you're using Perl for a specific task - for example, retrieving data from a database, sending email, or processing HTML form submissions - you won't find functions in Perl that allow you to accomplish these tasks easily. We saw this last week in the code we wrote for processing forms submissions - we had to write several lines of complex code to accomplish this common task.
Programmers have addressed the need for accomplishing commonly needed but complex tasks by creating and freely distributing Perl modules. For database interaction, there are the DBI and and DBD modules, for email there is the Net::SMTP module, for CGI programming there is the CGI module, and so on. There are currently about 3500 modules available for Perl, and at least 150 of the most popular ones come with the ActiveState version of Perl.
When you use a Perl module, you make a special set of new functions available for use in your Perl script. By learning about Perl modules and making use of their functions, you can greatly simplify your programming efforts.
Before you can use a module, it needs to be in the "lib" subdirectory of your Perl directory. If you look there with Windows Explorer, all the files you see that have a .pm file extension are Perl modules (also look in the subdirectories of "lib").
To access the functions in a Perl module, you must invoke the module in your perl script with the use directive. The example below uses the Cwd module, which makes three new functions available in your script: cwd, getcwd, and fastgetcwd. This is a handy module to use if your script needs to know the current working directory. The system commands for this are different in Windows, UNIX, and Macintosh. The module knows how to implement the right calls for Cwd for the operating system you're using. This means that it's a good way to help provide portability of your code from one OS to another.
#!perl use Cwd; $dir = fastgetcwd; print $dir;
Some Perl modules allow you to specify directives indicating how you want to interact with the module. For example, with the CGI module, you can take direct advantage of its functions, or you can run it in an object-oriented programming mode. For this class, we're interested using its standard set of functions - we specify this by invoking the module with the ":standard" argument:
use CGI qw(:standard);
Note that ":standard" has a meaning that is specific to the CGI module - read the documentation on other modules to see if they have options such as this.
use directive. In the above example, the filename is Cwd.pm, but you leave out the .pm file extension when you invoke it.
use cwd; you will not successfully invoke the Cwd module.
File::Find - make sure you've spelled the module name correctly (this is actually the syntax to use when accessing a module within a file that contains more than one module - the "find" module is one of several modules in file.pm).
As mentioned above, to see the modules that come with the ActiveState version of Perl, go into the "lib" subdirectory of the Perl directory on your computer and look for files with .pm file extensions.
To see what a module can do, open an MS-DOS window and type perldoc module_name - for example:
perldoc Cwd
You can download and install more modules from the ActiveState web site by using the Perl Package Manager (PPM). This is a command-line utility that you can use to automatically download and install Perl modules. You can also use it to review your currently installed modules. Let's see more about at the ActiveState web site: http://www.activestate.com/Products/ActivePerl/docs/faq/ActivePerl-faq2.html
You can find even more modules at the Web site for the Comprehensive Perl Archive Network (CPAN): www.cpan.org. You'll probably want to start with the The annotated module list (it's big!).
Pragmas are invoked with the use directive, just like modules. However, instead of providing additional functions to your Perl script, pragmas alter how the Perl interpreter behaves. There are only 19 pragmas, and only a couple of them are commonly used: diagnostics and strict (you've probably noticed use strict; in the sample scripts in your book).
diagnostics is used to provide more verbose error messages when a Perl script fails, and strict is used to enforce good coding practices. We'll talk about strict more in a later class.
We can re-write our script from last week (for processing the submission from the birthday form) using the CGI module, like this:
#!perl
# Invoke the CGI module with ":standard" so that
# we can use the module's standard set of functions.
use CGI qw(:standard);
# Check to see if the inputs are valid
push (@errors, "your first name") unless (param('firstname') =~ /\w+/);
push (@errors, "your last name") unless (param('lastname') =~ /\w+/);
push (@errors, "a valid date for your birthday") unless (param('birthday') =~ m:^\d{1,2}/\d{1,2}/\d{1,2}$:);
push (@errors, "a valid email address") unless (param('email') =~ /^\S+\@\S+\.\S+$/);
# If there's any invalid data, print a page with the error messages, and exit the script.
if (@errors) {
print header;
print
start_html('Input Error'),
h2('Input Error'),
p, "Please click your browser's <I>back</I> button and enter:";
print "<UL>";
foreach $error(@errors) {
print "<LI>$error\n";
}
print "</UL>";
print end_html;
exit;
}
# If there weren't any errors, we can print the response page.
print header;
print
start_html('Your name and birthday'),
h2('Your name and birthday'),
p, b('Your first name: '), param('firstname'),
p, b('Your last name: '), param('lastname'),
p, b('Your birthday: '), param('birthday'),
p, b('Your email address: '), param('email');
print end_html;
Applications like these need to "remember" what happens from one page to the next, so that when we reach the end, we haven't lost the information that was entered in the beginning.
Let's do an example that's an extension of our "birthday" CGI application. First, add the following input field to the form in birthday.html
<INPUT TYPE="hidden" NAME="page" VALUE="1">
Here's the revised birthday.pl script:
#!perl
# Invoke the CGI module with ":standard" so that
# we can use the module's standard set of functions.
use CGI qw(:standard);
# Check to see if the inputs are valid. First we need to
# know which form submission is coming in. Check the
# HIDDEN input field "page" to see if this is from the
# first form or the second form
if (param('page') == 1) {
push (@errors, "your first name") unless (param('firstname') =~ /\w+/);
push (@errors, "your last name") unless (param('lastname') =~ /\w+/);
push (@errors, "a valid date for your birthday") unless (param('birthday') =~ m:^\d{1,2}/\d{1,2}/\d{1,2}$:);
push (@errors, "a valid email address") unless (param('email') =~ /^\S+\@\S+\.\S+$/);
}
else {
push (@errors, "your favorite color") unless (param('color') =~ /\w+/);
}
# If there's any invalid data, print a page with the error messages, and exit the script.
if (@errors) {
print header;
print
start_html('Input Error'),
h2('Input Error'),
p, "Please click your browser's <I>back</I> button and enter:";
print "<UL>";
foreach $error(@errors) {
print "<LI>$error\n";
}
print "</UL>";
print end_html;
exit;
}
# If there weren't any errors, we can print the appropriate
# response page.
print header;
if (param('page') == 1) {
print
start_html('Your name and birthday'),
h2('Your name and birthday'),
p, b('Your first name: '), param('firstname'),
p, b('Your last name: '), param('lastname'),
p, b('Your birthday: '), param('birthday'),
p, b('Your email address: '), param('email'),
start_form,
p, b('What is your favorite color? '), textfield('color'),
hidden(-name=>'firstname', -default=>param('firstname')),
hidden(-name=>'lastname', -default=>param('lastname')),
hidden(-name=>'birthday', -default=>param('birthday')),
hidden(-name=>'email', -default=>param('email')),
p, submit,
end_form;
}
else {
print
start_html('Your name, birthday, and favorite color'),
h2('Your name, birthday, and favorite color'),
p, b('Your first name: '), param('firstname'),
p, b('Your last name: '), param('lastname'),
p, b('Your birthday: '), param('birthday'),
p, b('Your email address: '), param('email'),
p, b('Your favorite color: '), param('color');
}
print end_html;