1) Read chapters 3, 4, 5. About each chapter, make up and answer 3 good questions, suitable for use on an exam.
2) In class on Thursday, I will ask each "volunteer" to read their favorite question, then answer it. Everyone else will madly take notes.
3) It is very likely that I will collect your written queries and answers on Thursday, so this is a GOOD TIME TO WRITE THEM DOWN carefully.
These notes for this week will primarily contain Perl information that's not in the G text, and lists of key concepts I expect you to cover in your home-made queries.
For example: The m operator.
Page 42 shows a script in which this line occurs:
if ($accept_types =~ m|image/gif|)Normally, we would expect to see something like =~ /matchThis/. But in fact the /stuff/ syntax is a "short cut" for the more general m (match) operator, which consists of mx....x where x can be ANY character, and ... represents the regular expression for matching. When you use slashes, the m is assumed. When the expression is going to contain slashes, it is often easier to use the m|expre/ssion| syntax, than it would be to 'escape' the slashes with backslashes. That would produce
=~ /image\/gif/
instead of
=~ m|image/gif|
but you can do it either way.
Words you'd better understand:
content-length header
server redirection
the expires header
the pragma header ("pragma" means something we just stuck in, which
doesn't match the rest of the language.)
status codes
non-parsed headers
Chapter 4: Forms and CGI
This is one of the most important chapters in the book, obviously.
FORM tag
INPUT tags: text, password, radio buttons, checkboxes. VALUE fields
for defaults.
Hidden text fields.
Submit buttons
SELECT tags: menus and scrolled lists.
Multiline Text Fields
Understanding the decoding process
On page 62, we get to some interesting material. In essence, they're writing the program I asked you to develop - the one which reads in a form and puts the data into an associative array. We need two Perl constructs to understand this section: procedures, and references to variables.
Procedures ("subroutines") have a simple syntax.
sub fixit
{
local ($fixup);
$fixup = $_[0]." is fixed.";
return $fixup;
}The input parameters of a subroutine are referred to as $_[0], $_[1], etc. If this line occurred:
print &fixit("Michael");
the result would be
Michael is fixed.If you ever see a Perl subroutine with no RETURN, but which nevertheless returns a value, it's using an "implicit return". The last value assigned to a variable inside the routine, wherever that was, is the value returned by the subroutine. It's much clearer to use RETURN, but Perl programmers sometimes love to make tight, cryptic code.
Call by Reference is the technique used to pass an array to a subroutine, in such a way that the subroutine can put data into the array. Its opposite is call by value, which means "just copy the array's data into a temporary array", thus providing read-only access to the original data.
In the example on page 63, we see the following line:
&parse_form_data (*simple_form);parse_form_data is being called as a procedure rather than as a function (that is, nobody cares what value it returns) because its output will fall into the array named simple_form. The * means "call by reference".
Here's my commented version of the parse_form_data program. I'm not going to put this one into the formatted character style, because it spreads out too much on the browser.
sub parse_form_data # from pages 64 and 65 of G.
{
local (*FORM_DATA) = @_; # Provide
our own name for the input array
local ($request_method,
# will separate GETS from POSTS
$query_string,
# will store our main input
@key_value_pairs,
# will store results of stage one of nibbling
$key_value,
# one piece (pair) of stage one of the nibbling
$key, $value);
# the pair, at stage two of the nibbling process
#####################
# Part 1: Get data to work on
#####################
$request_method=$ENV{'REQUEST_METHOD'}; # environment:
# How did data come to us?
if ($request_method eq "GET")
# Note use of 'eq' for string match
{
$query_string = $ENV{'QUERY_STRING'}; # Notice $ENV is associative?
}
elsif ($request_method eq "POST")
# The only other legal option
{
read (STDIN, $query_string, $ENV{'CONTENT_LENGTH'};
}
else
{
&return_error (500, "Server Error", "Server uses unsupported method");
}
#######################
# Part 2: Munch data into key value pairs, in two steps
#######################
# Query string looks like key1=value1&key2=value2&key3=value3
@key_value_pairs = split (/&/, $query_string);
# @key_value_pairs now contains data like this:
#
key1=value1
#
key2=value2
#
key3=value3 etc
# These are in locations $key_value_pairs[0], $key_value_pairs[1], etc.
foreach $key_value (@key_value_pairs)
# Loop across the array
{
($key, $value) = split (/=/, $key_value)
# $key now contains "key1", and $value contains "value1"
$value =~ tr/+/ /; # Translate all the plusses in $value into blanks.
$value =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;
# $value now has all its embedded hexadecimal stuff (like %4F)
# Translated into the corresponding characters (like "!")
######################
# Now, put key-value pairs into the associative array!
######################
# Here's the
simple version, for teaching purposes (it's just a comment.)
# $FORM_DATA{$key} = $value; # Note {curly brackets <- associative}
# Here's the more
complex version that's in the text. It supposedly manages
# Cases where two
or more values arrive for the same key.
# I BELIEVE THIS CODE
TO BE WRONG. See below.
if
(defined ($FORM_DATA{$key}) # Did one such already arrive?
{
$FORM_DATA{$key} = join ("\0",$FORM_DATA{$key}, $value);
}
else
{
$FORM_DATA{$key} = $value; # as befire
}
} # END of the foreach
} # END of the program
Where the author used 'join', I personally would have used
$temp = $FORM_DATA{$key}."\0".$value;
$FORM_DATA{$key} = $temp;
For two reasons. First, because the construction looks more like my mental image of stringing together three items, than that "join" operator. Second, 'join' is defined to operate on entire arrays. It is supposed to take TWO arguments, like this example.
@items = ("There","are","five","words","here.");
$sentence = join (" ",@items)
print $sentence."\n";will print out the single string $sentence as follows:
There are five words here.
SO... I believe that the example above SHOULD have had parens on it, to make an implicit array, like this:
$FORM_DATA{$key} = join ("\0",($FORM_DATA{$key}, $value));
The return_error subroutine on page 66 is boring, so we won't discuss
it.
The Graphics Example
The program on pages 68-69 is interesting and will be discussed in class. It uses a library we haven't yet discussed.
--- and onward to chapter 5, for Thursday! --