Beginner's Introduction to Perl 5.10, Part 2
by chromatic , Doug SheppardMay 07, 2008
for statement). Now it's time to interact with the world.
This installment discusses how to slice and dice strings, how to play with files and how to define your own functions. First, you need to understand one more core concept of the Perl language: conditions and comparisons.
Comparison operators
Like all good programming languages, Perl allows you ask questions such as "Is this number greater than that number?" or "Are these two strings the same?" and do different things depending on the answer.
When you're dealing with numbers, Perl has four important operators: <, >, == and !=. These are the "less than," "greater than," "equal to" and "not equal to" operators. (You can also use <=, "less than or equal to," and >=, "greater than or equal to.)
You can use these operators along with one of Perl's conditional keywords, such as if and unless. Both of these keywords take a condition that Perl will test, and a block of code in curly brackets that Perl will run if the test works. These two words work just like their English equivalents -- an if test succeeds if the condition turns out to be true, and an unless test succeeds if the condition turns out to be false:
use 5.010;
if ($year_according_to_computer == 1900) {
say "Y2K has doomed us all! Everyone to the compound.";
}
unless ($bank_account > 0) {
say "I'm broke!";
}
Be careful of the difference between = and ==! One equals sign means "assignment", two means "comparison for equality". This is a common, evil bug:
use 5.010;
if ($a = 5) {
say "This works - but doesn't do what you want!";
}
You may be asking what that extra line of code at the start does. Just like the use feature :5.10; code from the previous article, this enables new features of Perl 5.10. (Why 5.010 and not 5.10? The version number is not a single decimal; there may eventually be a Perl 5.100, but probably not a Perl 5.1000. Just trust me on this for now.)
Instead of testing whether $a is equal to five, you've made $a equal to five and clobbered its old value. (A future article will show how to avoid this bug in running code.)
Both if and unless can be followed by an else statement and code block, which executes if your test failed. You can also use elsif to chain together a bunch of if statements:
use 5.010;
if ($a == 5) {
say "It's five!";
} elsif ($a == 6) {
say "It's six!";
} else {
say "It's something else.";
}
unless ($pie eq 'apple') {
say "Ew, I don't like $pie flavored pie.";
} else {
say "Apple! My favorite!";
}
You don't always need an else condition, and sometimes the code to execute fits on a single line. In that case, you can use postfix conditional statements. The name may sound daunting, but you already understand them if you can read this sentence.
use 5.010;
say "I'm leaving work early!" if $day eq 'Friday';
say "I'm burning the 7 pm oil" unless $day eq 'Friday';
Sometimes this can make your code clearer.
while and until
Two slightly more complex keywords are while and until. They both take a condition and a block of code, just like if and unless, but they act like loops similar to for. Perl tests the condition, runs the block of code and runs it over and over again for as long as the condition is true (for a while loop) or false (for a until loop).
Try to guess what this code will do:
use 5.010;
my $count = 0;
while ($count != 3) {
$count++;
say "Counting up to $count...";
}
until ($count == 0) {
$count--;
say "Counting down to $count...";
}
Here's what you see when you run this program:
Counting up to 1...
Counting up to 2...
Counting up to 3...
Counting down to 2...
Counting down to 1...
Counting down to 0...
String comparisons
That's how you compare numbers. What about strings? The most common string comparison operator is eq, which tests for string equality -- that is, whether two strings have the same value.
Remember the pain of mixing up = and ==? You can also mix up == and eq. This is one of the few cases where it does matter whether Perl treats a value as a string or a number. Try this code:
use 5.010;
my $yes_no = 'no';
say "How positive!" if $yes_no == 'yes';
Why does this code think you said yes? Remember that Perl automatically converts strings to numbers whenever it's necessary; the == operator implies that you're using numbers, so Perl converts the value of $yes_no ("no") to the number 0, and "yes" to the number 0 as well. Because this equality test works (0 is equal to 0), the condition is true. Change the condition to $yes_no eq 'yes', and it'll do what it should.
Things can work the other way, too. The number five is numerically equal to the string " 5 ", so comparing them to == works. When you compare five and " 5 " with eq, Perl will convert the number to the string "5" first, and then ask whether the two strings have the same value. Because they don't, the eq comparison fails. This code fragment will print Numeric equality!, but not String equality!:
use 5.010;
my $five = 5;
say "Numeric equality!" if $five == " 5 ";
say "String equality!" if $five eq " 5 ";

