Category Archives: Perl

It’s a Wonderful CGI Script!

With your script all written and your database in place, you’re probably chomping to see it all work. But the most important thing to remember with CGI scripts is to make sure they’re stable. Always have a trusty engineer take a look at your scripts to make sure they don’t do anything stupid.

Once you get the go-ahead, put ‘em up and push ‘em live. If you want to see everything all in one place, take a look at the I finished code (cut and paste at will).

So there you have it:Your very own, living, breathing CGI script. As you can see, most of CGI is just standard Perl, with a few changes here and there to give it that bonus CGI flavor you have to pay so much extra for at Starbucks.

So with the power of CGI firmly in your paw, what’re you going to do with it? Well, that’s up to you. The mighty CGI knowledge has been known to drive some mad. I know many scripters, who having learned the art, decided to head into the thickest forests they could find to build shanties and bombs. Knowing how to script CGI is the easy part of the equation. The toughest part is figuring out how to use your power to do something worthy, while maintaining your sanity and the sanity of the sysadmins who oversee the machines that run your scripts.

The CGI Difference

The CGI Difference

CGIs process input differently than old Perl scripting does – and this, my friends, is the only difference you’ll find between the two. Once the CGI scripts process the input, it becomes data, which is treated pretty much the same way by both CGI and Perl scripts. CGI input can be retrieved in two different ways:”get” and “post.” If you’re absolutely sure what type of input you’ll be getting, then you only have to use one type of input retrieval. But if it’s the least bit possible that whoever writes the form won’t mark the input type correctly (and really, who knows what they’ll do), then you have to catch all the possible types of answers. This involves a simple two-step process, handled with an if/else statement.

    if ($ENV{'REQUEST_METHOD'} eq "GET") {



    		$in = $ENV{'QUERY_STRING'};



    	} else {



    		$in = <STDIN>;



    	}


This statement asks the server if the request method (the way in which the server gave you the information) is “get.” If so, the script will read the information from the Query String into a variable called $in. Otherwise, it’ll read it in through standard input just like it would a normal Perl script.

Turning Perl into CGI

Turning Perl into CGI

So now you have the Perl basics down, and you’re no doubt itching to put that know-how to work. Well, being acquainted with Perl’s one thing, but turning Perl into a keen CGI script is a whole ‘nother ball of wax. Hence, Lesson Two of Colin’s wonderful world of scripting.

These days there are all kinds of super wonderful libraries and Perl Modules that can make CGI scripting easier and niftier, but we’re all about basics here today. My daddy once told me that you’ve got to learn to walk before you can river-dance. So today we’re going to stick to super basic, almost prehistoric, though still really nifty Perl to put together today’s little project. Tune in at a not-so-distant-future date when this simian will take a look at the Perl CGI module.

Before we begin, there are a few more things you must know before you tackle phase two.

  1. You need to know how to make a form in HTML. If you can’t to do this yet, learn it and come back. It’s really easy and should only take five minutes to learn (ten if your last name’s Gump).
  2. Scripting requires a certain concentration, which can be brought on by the right music. Personally, I’ve found The Pixies and They Might Be Giants to be proven script enhancers.
  3. CGI is frustrating. Rather than lash out at a co-worker, little brother, or computer, a big heavy punching bag can help ease the strain. (Of course, if things prove too much for you, you can always go back to stealing other people’s scripts.)

And that should do it. With these things under control, you’re ready to jump into today’s lesson. We’ll examine the differences between Perl CGI and Perl scripting, and we’ll build a small script to illustrate just how nifty CGI really is.

Additional Functions

Additional Functions

Great, you’ve almost got it. Just look at you! My little Perl Jedi! Of course, even a Jedi needs a few weapons. Here’s a few extra things to help you write the perfect Perl script to master the Force and all that garbage.

Splitting

Splitting is a function that will save you lots of time and money (well, time, at least). It looks for a pattern in a string and splits up the string into an array based on the pattern. Have a look.

 #!/usr/local/bin/perl

 

 # I have a string.



 $stuff = "Colin is so cool";



 # I decide that I want to split it up by spaces into an array.



 @stuff = split (/ /, $stuff);



 # I then want to print out each slot on a different line.



 for ($i = 0; $i <= $#stuff; $i++) {



 	print "Slot $i:$stuff[$i]\n";



 }



 # Find out how many words there were like this.



 print "There were $#stuff words.\n";

Play around with this tool a little bit, and you’ll find out just how useful it really is.

Search and Replace

If you always misspell the same words as I do, then you’ll love Search and Replace. Here’s how it works:Place =~ s/searchstring/replacestring/gi; after the string you want to run Search and Replace on, replacing searchstring and replacestring with the items you want searched and replaced, like so:

 $stuff =~ s/bad/bad bad leroy brown/gi;

So if I wanted to fix all my “e”s before “i”s, I might do something like this:

 # I have this string:



 $stuff = "beleive releive greive";



 # I want to fix all the mistakes.



 $stuff =~ s/ei/ie/gi;



 # Then I want to print out the output.



 print "$stuff";

The niftiest part is that you have a couple of different options with this tool. At the end of statement, there are two letters:”g” and “i.” Those are two options:”g” tells the command to search and replace all occurrences of the string, and “i” tells it to ignore case. One other cool option is the “o” option, which only replaces the first occurrence. (It’s the opposite of the “g” option.) You can use one, all, or none of these options with the command.

Quick Search

Last, you can even use it to tell if something is in a string. Say that you wanted to do something only if the string contained the word “cool.” The hard way to do this is to split up the string and run a loop through the array, looking for the word. Thankfully, there’s any easier way:a quick search.

 $stuff =~ /cool/

This statement would return a true value if the string contains the word “cool” and return a false value if it didn’t. You can also do the reverse:

 $stuff != /cool/



… which would return a true if the string doesn’t contain the word “cool” and a false if it does. Then you can use it in an if statement like so:

 if ($stuff =~ /cool/) {



 	statements



 }



All kinds of niftiness!

Now that I’ve given you a taste of Perl, no doubt you’re probably jonesing to actually do something with it. Read on to learn how to turn Perl into CGI.

Perl With This Loop, I Thee Wed

With This Loop, I Thee Wed

So you know if/else, you know variables, and you know assignments, but I bet you don’t know loops. That’s right, my friend, you’re not there yet. Even the Karate Kid had a few things to learn from Mr. Miagi.

Anyone who has used a computer language should be familiar with the format of loops. If not, don’t worry too much about it, because I’m paid the big bucks to show you how it’s done.

Loops fall under a part of scripting with the apt name “command structure.” Usually loops form the body of the script, which sends out the information and instructions to the rest of the script. Loops repeat again and again and stop only when certain parameters are met. Enter Rule #6.

Rule #6: All loops must end. It sounds simple, and for the most part it is. You just have to keep track of your variables through every step of the loop (revisit Rule #3).

The essential format of a loop looks like this (although they can include if/else statements and even more loops):

command (statement) {



	statements;



}

The basic kinds of loops in Perl are the for loop, the while loop, and the foreach loop.

The For Loop

The for loop is, without a doubt, my favorite loop because it’s elegant and self-contained. I fell in love with it while working with JavaScript and continued the affair through Java. It still burns strong with Perl. Its format is the most complicated of all of the loops, but complexity in computing usually means more power — or that’s what I keep telling myself. Here’s what it looks like:

for ($i = 0; $i <= $#stuff; $i++) {



	print "$stuff[$i]";



}

In the for loop, you define a variable that exists only within the loop. It doesn’t have to be called $i, but it’s a stand-by variable for incremental variables. I defined the variable $i to equal 0. Then I told the loop to keep looping, as $i is less than or equal to the number of slots in the array @stuff. And then I told it to add 1 to $i at the end of each pass through the loop. Next I had the script print the @stuff array slot that $i represented. So on its first pass through the loop, it would print $stuff[0]. On the second pass, it would print $stuff[1]. This pattern would continue until the condition set was no longer valid.

I love these. My vision of the perfect woman is one who can write a killer for loop and will listen to Pixies songs all day long. (Come to think of it, if you’re out there and you can write a for loop to play a Pixies song, send me a note.)

The While Loop

The while loop is just like the for loop, only not as self-contained. A sample for loop would look something like this:

$stuff = <NAMES>;



while ($stuff ne "bob") {



	print "$stuff";



	$stuff = <NAMES>;



}

This code executes the statements inside the loop as long as the variable $stuff doesn’t equal “bob.” This loop runs the greatest risk of never ending, because it doesn’t rely on a value test to stop as the for loop did. Rather, you have to define a variable outside the loop and have the value change somewhere inside. It’s tricky.

Foreach Loop

Foreach loops are kind of cool. They’re like a lazy version of the for loop. Take a look:

foreach $slotnum (@stuff) {



	print "$slotnum";



}

One slot at a time, this loop will take the lowest value and assign it to $slotnum to be used as a wild-card variable later on. So the @stuff array will start with slot number 0 and go all the way to slot 100 (if there is one). Or it’ll stop if it runs out of slots. The foreach loop is really useful for running through associative arrays since their slots aren’t numbered. Check this out:

foreach $slotname (keys (%stuff)) {



	print "$stuff{$slotname}";



}

This code grabs each key value to the %stuff array one value at a time. (Have you already forgot about associative arrays? Go back to Scalers, Arrays, and Associative Arrays, do not pass Go, and do not collect $200.) It does this by using the built-in Perl function keys and then printing out the value of each slot. Don’t worry:We’ll get to printing. In the meantime, wax on, wax off, wax on, wax off.

Righty-o! Now you’re almost ready to Perl, but you still need something to manipulate.

Perl Operators

Perl Operators

What Number Please?

Without operators, there is no point to scripting. Assigning values to variables and stuff would serve no purpose, unless you just wanted to rename the number one $that_number_that_I_can_never_remember – and we all have to admit that’s a little bit stupid, right?

There are three different types of operators:assignment, comparison, and mathematical. Assignment operators give a value to a variable, comparison operators compare two values and give a third value based on what they find, and mathematical operators do the math so you don’t have to. And here they are:

Assignment Operators

= Makes the value of the variable on the left side equal to whatever is on the right.
+= Adds the value of the right side to the left side and makes the variable on the left equal to it.
-= Same as above, only subtracts instead of adds.

Comparison Operators

< Returns a true value if the value on the left is less than that on the right. Otherwise false.
> Same as above, but the other way around.
>= Returns a true value if the value on the left is greater than or equal to that on the right. False if not.
<= Are we seeing a pattern here?
== Returns a true value if the values on both sides are equal; otherwise returns a false.
eq The same as above, but rather than comparing values, it compares strings of text.
!= Returns a true value if the value on the right is not equal to that on the left. False if they are equal.
ne Again, same as above, but for strings of text.

Comparison Operators are perfect for those if/else statements I talked about. They work something like this:

#I assign the value of 5 to $stuff.

$stuff = 5;

# Then I compare it and react to its value.

if ($stuff < 5) {

print “Runt!”;

} elsif ($stuff >= 6) {

print “Too big, man!”;

} else {

print “I guess that’ll do.”;

}

Mathematical Operators

* Multiplies the two values together.
/ Divides two values.
+ Adds two values.
- Subtracts two values.
++ Adds 1 to the value on the left (so if $i were equal to 1, $i++ would equal 2).
Subtracts 1 from the value on the left.

You get the idea. Of course, with the exception of the last two operators, mathematical operators aren’t any good unless you use an assignment operator for storing the value. For these to be of any use, you’d have to do something like this:

 $stuff = 5 * 3;



Scalers, Arrays, and Associative Arrays

Scalers, Arrays, and Associative Arrays

All variables are one of three different types:scalar, array, or associative array. What’s the difference? A scalar variable is the catch all. It can hold numbers, letters, phrases, whatever. It always has a “$” (dollar sign) before it. So if I wanted to assign a value to the variable $stuff, here’s how I’d do it:

A word:$stuff = "rules";



A phrase:$stuff = "Colin Rules!";



Numbers:$stuff = 2;



You can even add and subtract like this:

$stuff = 2 + 2;



$stuff = 4 - 2; 



$stuff would then equal 4 and 2, respectively.

Assignments to variables always happen from left to right. 2 + 2 = $stuff; is not only invalid, it’ll get you killed in some neighborhoods. I’m not kidding around.

An array variable is a variable that holds many scalar variables in numbered slots. These slots are added as needed so the variable can grow dynamically. It can shrink, too, but that’s just a waste of time. Array variables usually have the @ (at symbol) in front of them. When declaring slots individually, you use a $.

You can declare as many slots as you want right away by doing this:

 @stuff = ("1","2","ten","Colin Rules","Perl's for winners"); 

To get at each slot, you call it by number. So $stuff[3] is equal to "Colin Rules", and $stuff[1] is equal to "2". Wait! Why isn’t slot 4 "Colin Rules"? That’s easy. Perl, like JavaScript starts indexing at zero. So $stuff[0] equals "1", $stuff[2] equals "ten", and so on. You can find out how many slots the array has by looking at the built-in variable $#stuff. For instance, the value of the @stuff array we defined above would be 4. (Remember, counting starts at 0.)

To declare one slot at a time, do this:

 $stuff[0] = "2000000"; 

Note that $stuff[0], $stuff[30], or $stuff[whatever] have no relation to $stuff from the example above. The only thing they share is the same name, which doesn’t conflict because the two variables are of different types. Generally it’s good form not to give your variables the same name — which is a perfect segue into Rule #5, recently recovered in a dig in Harlem of all places.

Rule #5 All variables must be named intuitively. Sure, $a may be much quicker to write than $apple, but when you have to go back later to dissect everything, you’ll have no idea that $a stands for apple.

Name it for what it does. You can use up to 4 million characters (or something like that) to name your variable, so don’t worry about running out of room. And don’t run it all together, either. You can’t use spaces in variable names, but you can use an underscore to separate the words. For instance, $book_page_i_am_on is a lot easier to understand than $bookpageiamon.

What characters can you use in a variable name? Choose from aAbBcCdD to xXyYzZ. But don’t use !, @, #, $, %, ^, &, *, (, ), ~ or any other character that deviates from the alphabet. If you didn’t sing it in kindergarten, don’t use it now.

All righty! The last type of variable is the associative array. Associative arrays are great for storing related information. They are the easiest of the two arrays (in my mind), because you don’t have to remember what slot you stuck something in. Associatives usually start with a % (percentage sign), but like the other arrays, when you call a slot individually, use the $. To declare an associative array, simply do this:

%stuff = ("sport","basketball","bike","trek","name","Don't remember",



"Age","Not old enough to drink");

Every other value in this example is the key to the one after it. So $stuff{'sport'} is "basketball", and $stuff{'name'} is "don't remember", and so on. To declare one slot at a time, do this:

$stuff{'girlfriend'} = "Looking. Any leads? Call me";

OK, now you’ve got those variables, but what good are they unless you can compare them to something? No good:That’s what! To give those variables a purpose, you need Perl operators.

Perl – The Rules of the Road

The Rules of the Road

What do you need to know? It’s simple. Just follow these basic rules.

Rule #1: Always put this line at the top of your Perl script, no excuses:

 #!/usr/local/bin/perl 

It tells the server running your script that what follows isn’t Russian on acid but Perl. The server likes Perl, it just needs to know what it is. So don’t forget to start with this line. Otherwise you’ll spend hours trying to find what’s wrong with your syntactically correct script only to discover that you left out the most basic thing.

Rule #2: Always put a semicolon at the end of every line. If you don’t, you’ll never, ever, ever get a script to work. So just do it.

Rule #3: Put comments everywhere you can. What are comments? Comments are complete sentences that describe what the script does at a certain point. Any line beginning with a “#” mark is a comment line, with the exception of the line in Rule #1. Look at the example below to see how comments might be useful.

# In the following code, I’m going to create a variable that contains
# the info that will go into a log. But I’m going to keep the
#  formatting really simple so it’ll be displayed in
# an easy-to-read fashion.

my $in{‘logdata’} = <<END;
$in{‘name’}
$in{‘formelement1′}   |   $in{‘radiobutton2′}
$in{‘checkbox1′}        |   $in{‘checkbox2′}
END

As the author of this script, you probably know the purpose of that variable, but what if someone else had to work with the script? You wouldn’t want them to spend the rest of their lives deciphering your uncommented code (unless they’re being paid by the hour). So try to make it easy on everyone else.

Rule #4: Clean code is maintainable code. Writing clean code falls under the good citizen laws, as does Rule #3. Just because you could write something like this:

 for ($i=0;$i<=$#blah;$i++){if ($blah[$i]~=/punk boy/g;)



 {print  "I hate this code";}else { print "nappy";}}

 

… doesn’t mean you should. It may not create any errors, but it’s difficult to read, not to mention just plain ugly. Even with comments, it would take a person days to figure out that this is nothing more than a “for” loop, running through the “blah” array, looking for the phrase “punk boy.” If the phrase exists, it prints “I hate this code”; if it doesn’t, it prints “nappy.” It’s a lot prettier and easier to understand if you do it like this:

for ($i = 0; $i <= $#blah; $i++) {

 

 	if ($blah[$i] ~= /punk boy/g;) {

 

 		print "I hate this code";

 

 	}else {

 

 		print "nappy";

 

 	}

 

 }

All clear? Don’t worry, Grasshoppper; you’ll get it.