5. Echo Environment Variables

In steps 5 & 6, we will go a little further into the programming facilities provided by Perl. The discussion will be limited, primarily, to those needed to accomplish the task. For context and related features, see the Perl Basics discussion or a standard text, such as Learning Perl.

Recall from the discussion of CGI that the server places values in a set of environment variables which can be accessed from within CGI programs as a special kind of global variable. For programs invoked with the method, GET, they provide the only means of passing data to the program. For programs that use POST, data from the user are passed through STDIN, which will be discussed next. However, HTTP protocol data are passed through environment variables for both GET and POST methods.

The server makes environment variables available to CGI programs in different ways according to the programming language in which the programs are written. The discussion here is concerned only with handling environment variables with Perl.

The primary goal for step 5 is understanding what the environment variable data look like and how they can be accessed by a Perl program. We won't do anything with the data except print it as a formatted list. You may wish to refer to the Echo Environment Variables program, below, during the discussion. Note that most of the program is similar to the Hello, World, in HTML program with respect to HTML boilerplate. The lines to focus on are near the bottom where data for an unordered list are generated. Within the beginning and end tags are two Perl statements. Those two statements are our concern here.

There is a good deal of magic expressed in those two statements. They will make a lot more sense, as will the code in step 6 that follows, if we pause for a moment and talk about Perl variables and names.

The initial character of a Perl name identifies the type of variable or entity:

$name
scalar variable, either a number or string; Perl does not differentiate between the two, nor does it differentiate between integers and reals.

@name()
array ; Perl uses the "at" symbol and parentheses to designate an array as a whole. However, it considers individual elements in an array scalars and, hence, switches to the "dollar" sign to designate a specific element in an array. Furthermore, the index for an element of an array is included within square braces, not parentheses. Thus, $name[0] is the first element of the array, @name = ( "john", "bill", "mary"), and has the value "john".

%name{}
associative array ; a special, 2-dimensional array, ideal for handling attribute/value pairs. The first element in each row is a key and the second element is its associated value. Instead of using a number to index an associative array, you use a key value, such as $name{"QUERY_STRING"}, to reference the value associated with that particular key, in this case QUERY_STRING. Since the associated value is a scalar, the variable has a $ prefix. Note, also, the use of curly braces ({}) as delimiters.

&name()
function ; the ampersand is placed before the name when the function is called; if the function takes arguments, they are placed within parentheses following the name of the function.
When the functions is defined, the name is preceded by the key word, sub, but does not have the ampersand prefix.; code for the subroutine is then placed within curly braces ({}) following the name.

We can now go back to the program. Look at the line two-thirds of the way down that begins with the keyword, foreach. We'll unwind it first.

The server provides the environment variables to the CGI Perl program in the form of a special associative array it creates, called %ENV. Each row of %ENV, then, contains a key, which is the name of an attribute, and the value that is associated with that attribute.

keys is a built-in function that takes an associative array and returns a list (one-dimensional array) of its keys. Thus, one would expect to see the expression, keys (%ENV); Perl makes the parentheses optional with keys and they are omitted here.

$key is a scalar variable that can receive a specific key value, which it does by virtue of the foreach operator that precedes it in the line. foreachtakes a list of values and assigns them, one by one, to the scalar variable that follows it. Note, that the choice of "key' in "$key' is arbitrary.

Thus, to paraphrase the whole line: $key iterates through the list of keys produced by the built-in function, keys, from the associative array, %ENV, built by the server.

On to the next line, in which keys and associated values are printed. The line is relatively straight-forward once one thing is understood: Perl interprets variables within double quotation marks. Consequently, the print statement begins by printing the HTML tag for a new list item. It then interprets $key according to its current key value, which was assigned, iteratively, in the preceding foreach statement. It next prints the equal sign. Finally, it prints the array value indexed by the current value of the $key variable. Note that this array value is referred to as $ENV{$key}. The dollar sign prefix is used since only a single, or scalar, value is being referenced. Note, also, the use of curly braces, since the whole thing is an associative array.

That's a lot to swallow, perhaps, in two lines of code, but such is the nature of Perl -- very succinct, but also very powerful. There's an initial hump to get over, but the hump is not all that high. Then you can begin the long climb toward more and more sophisticated uses of Perl, if it's to your taste.

Echo Environment Variables Program

#!/usr/local/bin/perl

print "200 ok\n";
print "content-type: text/html\n\n";

print "<HTML>\n";

print "<HEAD>\n";
print "<TITLE>echo cgi env. vars.</TITLE>\n";
print "<H2>Echo CGI Environment Variables</H2>\n";
print "</HEAD>\n";

print "<BODY>\n";
print "<HR>\n";
print "<H3>Environment Variables</H3>\n";
print "<UL>\n";
foreach $key (keys %ENV) {
  print "<LI>$key = $ENV{$key}\n";
  }
print "</UL>\n";
print "</BODY>\n";

print "</HTML>\n";

Write and test an Echo Environment Variables program. You can also execute the program, above: Echo Environment Variables.