home -- outline -- lectures -- assignments -- discussion -- tips -- links -- | |
![]() ![]() |
|
![]() |
Wednesday February 25 CGI, Perl and Dynamic Pages We have looked at two control structures so far, if and while. if is useful in those situations where we want to do something under a certain set of conditions. while is useful when we want to do something repeatedly, until a condition changes. When we were reading files, we were reading them WHILE there was still something left to read. We cheated a bit (in a fairly good way) by doing the reading and testing at the same time. This gave us the following: while (< FILE >){ print $_;}In this the test, < FILE >, is actually the same as the read. Another way to do this, that is somewhat less elegant, but perhaps a bit clearer, would be to read in a line, test it, and exit if we have run out of file. This would look like: $_ = < FILE > ; while ($_){ print $_; $_ = < FILE > ;}Before we enter the while, we set the $_ to the value of the read. Then, we loop through the printing of that line and obtaining the next one, until that variable is set to "". We can step through other things using while. For example, we can write a script that is handed a number and generates a list of all numbers up to it. But while is not the only control structure that we have. We also have for. for is similar to while in that it has a test that it runs each time through the loop. It differs in that it has three explicit parts associated with the test. It has an initialization, a test condition and a reinitialization.
for ($counter=0; $counter <= $number; $counter=$counter+1){ print "$counter ";};This gives us the same behavior as we had with the while. Finally, we have foreach. foreach is designed to let you step through a list of objects and do something with each one. A list is just a set of objects hooked together by ","s. We can use foreach to implement a countdown with the following: foreach $counter (10,9,8,7,6,5,4,3,2,1,'Boom'){ print "$counter < br > ";};Which runs like this. In the foreach, the first element (the variable $counter) is set to each of the elements of the list in turn. The first time through the loop, it is set to "10", then "9", then "8"... well you get the idea. Note that we now have the idea of a list. In perl, lists are implemented as arrays. We can actually take a list of elements and set it to an array. Then we can use the array in a foreach For example @countnums=(10,9,8,7,6,5,4,3,2,1,'Boom'); foreach $counter (@countnums){ print "$counter < br > ";};will do the same thing as the foreach above. Of course, this isn't as interesting as setting an array to the result of an operation that is more dynamic. split, for example, returns a list. Previously, we grabbed a set number of elements of that list explicitly. Using arrays, we can grab arbitrary numbers of those elements. For example: @chars=split//,$word; foreach $char (@chars){ print "$char < br > ";};will split a word into a list of characters and then foreach prints out the character. This gives us control structure, but, at this point, we have very few tests that we can apply as the test in our controls. One source of tests is provided by perl's pattern matching capabilities. The baseline pattern matcher in perl is m//. m// takes a pattern and matches it against the $_ variable. Other variables can be matched against by calling m// using =~ or !~. Both of these end up changing the variable that is used, however, so they should be used with caution. We can test to see if a string is part of a larger string by doing the following: $alpha="abcdefghijklmnopqrstuvwxyz"; $_=$alpha; if (m/$word/i) {print "You handed in a alpha string."} else {print "Better luck next time."};or $alpha="abcdefghijklmnopqrstuvwxyz"; if ($alpha =~ m/$word/i) {print "You handed in a alpha string."} else {print "Better luck next time."};The i following the pattern makes the matching case insensitive. We can add special characters to the match string if we please. For example, we can tell m// to match only against the beginning of a string by adding in a ^. $word="cde"; $alpha="abcdefghijklmnopqrstuvwxyz"; $_=$alpha; if (m/$word/i) {print "You handed in a alpha string."} else {print "Better luck next time."};matches... while $word="cde"; $alpha="abcdefghijklmnopqrstuvwxyz"; $_=$alpha; if (m/^$word/i) {print "You handed in a alpha string."} else {print "Better luck next time."};doesn't. We can test for arbitrary regular expressions using m// as well. The most important features associated with this is the use of | as an "or" within the test pattern and the use of [ ]s to indicate that any element within them can match. for example, to test is $_ is set to a Flintstone... if (m/Fred|Wilma|Dino|Barney|Betty/) {print "Sure, that's a Flintstone"} else {print "Slacker."};Or, to test is $_ is a vowel... if (m/[aeiou]/i) {print "Thanks Vanna"} else {print "Slacker."}; Now let's remember that this class is still about the Web, not perl. We're learning this stuff in order to be better able to create pages on the fly. Imagine, just for example (and the next assignment) that you have access to a collection of images (in a directory called We can imagine using our pattern matcher to find keywords that match an input request, using this to find one or more names, and then using those names to build page with a set of entries of images, descriptions, titles, etc... |