DISCLAIMER: THESE PAGES ARE STILL UNDER CONSTRUCTION. NO CODE EXAMPLE BEEN TESTED YET.

Introduction to Perl

Control Structures - for, foreach, while, if


[Previous Page] |[Next Page] Table of Contents: small | med | large

In Perl, there are several ways you can affect control flow. That is, you might want to execute a block of code several times, or you might want to execute something conditionally.


while loops [back to top]

A while loop will keep going until a continuation contidition is met. For instance,

	while($currentLine ne '') {
		my($currentToken, $currentLine)
					= split(/\s+/, $currentLine, 2);
		# Do something with the current Token...

	}
This will take a line of text and peel off a word at a time, assuming that the words are separated by whitespace (\s+ is equivalent to any series of spaces, tabs, and newlines). If you were writing a real parser, you would also want to take into account the possibility of one of the words itself containing spaces, and think about what happens with quotes and escaped quotes. Those situations come into play when parsing Inventor or Maya files. But if you are making your own configuration files, it is probably good enough.

split is a command intrinsic to Perl which breaks up a string into a list. It uses the first argument as a regular expression to determine what the separator is. In this case, I'm using whitespace. Other common ones are slash(/\//), underscore (/_/), and colon (/:/). The second argument is the string that I am splitting. Note that the split by itself will not alter the $currentLine. But since I assign to it on the left hand side of the =, it will hold everything remaining on the line.

Now, normally, split is used to break apart a line into all of the components. However, you can use the optional third arguement to limit the number of tokens. In this case, I use 2, so I only get the next token and "the entire rest of the line."

Another common example is to process the command line. These days, I tend to use GetOpt::Long to process any serious command line, but when people first start, they often use something like:

	while (scalar(@ARGV)>0) {
		my $currArg = shift @ARGV;
		# do something with the arg
	}

Incidentally, I don't make a lot of custom configuration files anymore. I tend to keep most of my data in Perl files to start. It saves me the trouble of writing a parser later.


for loops [back to top]

The basic structure of a for loop is:

	# $fs is frame start
	# $fe is frame end
	# $fi is frame increment
	for (my $frame = $fs; $frame<= $fe; $frame += $fi) {
		# do something with each $frame...
	}
You can probably figure it out just by looking, but I'll go over it anyway: The loop above is actually equivalent to the while loop:
	my $frame = $fs;
	while ($frame <= $fe) {
		# Do something with each frame

		$frame += $fi;
	}
	undef $frame;
Any for loop can be decomposed this way. But it is just a convenience to be able to express it in one line.

This loop basically takes a frame range and an increment and does something to each frame. You'll probably do that a lot in a pipeline.


foreach loops [back to top]

foreach loops are a really convenient way to do something to every element in an array. You could do this in a for loop like this:

	@elements = ('BigRed', 'Whitney', 'Courtney', 'Darcy', 'Carver');
	for( my $i=0; $i < scalar(@elements); $i++) {
		my $element = $elements[$i];
		# Do something with the element...
	}
but Perl offers the alternative of the foreach loop which will access each element of the array.
	@elements = ('BigRed', 'Whitney', 'Courtney', 'Darcy', 'Carver');
	foreach my $element (@elements) {
		# do something with the element
	}
This is much more convenient, and doesn't need the $i. A lot of the time, when you are iterating through the elements, you really don't care what the index was, so this saves you the hassle. A couple more notes:

Some other common uses of the foreach loop are:


conditionals - if and next if [back to top]

if is one of the simplest structures. Basically, it will only execute a code block if the condition is satisfied. For example, let's say you want to print a help message if someone executes your script without entering any parameters.

	if (scalar(@ARGV)==0) {
		$needsHelp = 1;
	}

	# process some stuff the help message would want to
	# know about...

	if ($needsHelp) {
		print "Some instructions about how to use this program\n";
		exit 0;
	}
There's an alternate version of this. You can also put the if after a single statement. I very rarely do this. In fact, I think the only time I do this is when I use next in a loop.

When you're using while, for, or foreach, you can jump to the next iteration prematurely by using next, or you can break out of the loop by using last. I will grant you that it's a little weird that they did't use "continue" and "break," but take what you can get.

This is used like:

	@elements = ('BigRed', 'Whitney', 'Courtney', 'Darcy', 'Carver');


	foreach my $element (@elements) {
		next if ($element eq 'BigRed');	# BigRed already graduated

		# Add all other elements to the image
		&renderToTeamPhoto($element);
	}
The above example will send each element to the user subroutine renderToTeamPhoto. However, for the first one, since it is 'BigRed', the conditional evaluates to true, so the next is executed. This is equivalent to saying:
		if ($element eq 'BigRed') {
			next;
		}
but it is just shorter. I only do this for next, and I try to keep the conditionals short (like only one line).

until, unless, and do/while loops [back to top]

Perl also offers a couple more sturctures with until and unless that allow you to define a terminating/continuing condition after the code block. In general, I don't like these because I prefer to see the condition up front, so I'm not going to go into these. If you really want to learn about these, read Learning Perl [SCHW97] and Programming Perl [WALL00] .


© 2001 Steve Hwan, hostname: @pacbell.net, username: svhwan
You should probably use the word "PERL" in the subject line to get my attention.
Last Modified: Wed Mar 28 21:40:30 2001