Conditionals

Conditionals are used to execute different bits of code based on the value of a given test. If the test is true, a block of code is executed; if the test is false, either execution continues to the next part of the script, or a different block of code is executed. Unlike loops, each block is executed only once.

if, ifelse, and ifelsif

The most common form of conditional is the if, and its variant forms ifelse and ifelsif. As you've seen, the if statement looks like this:

if ( test ) {
   # statements
}

The test is any expression, evaluated in a boolean scalar context for its truth value. Remember that everything except "", 0, and undef is considered true. If the test is true, the block is executed. If it's false, nothing happens and execution continues onto the next statement in the script.

Note that the block after the test (and, in the next two forms, after the else and the elsif) is always required, even if you only have one statement inside that block. You must always include the curly braces. The block doesn't have to be on different lines, as I showed here; you can format the brackets in any style you prefer. Short if statements tend to look neater on one line:

if ( $x ) { print "true!" }

To execute one block if the test is true and a different block if the test is false, use ifelse:

if ( test ) {
   # statements to execute if test is true
} else {
   # statements to execute if test is false
}

A common operation in all languages with ifelse-like constructs is that there are multiple nested if's and multiple else's, like this:

if ( test1 ) {
   # statements1
} else {
   if ( test2 ) {
      # statements2
   } else {
      if ( test3 ) {
         # statements 3
      } else {
         # and so on...}

To save a few keystrokes, or to avoid large amounts of indentation, Perl provides a third form of if conditional, the elsif, to compress these sorts of operations:

if ( test1) {
   # statements1
} elsif ( test2 ) {
   # statements2
} elsif ( test3 ) {
   # statements3
} else (
   # else statements
}

Note the difference between the nested if and separate if statements, like this:

if ( test1 ) {
   # statements1
}
if ( test2 ) {
   # statements2
}
if ( test3 ) {
   # statements3
}

Use separate if statements, then, regardless of the outcome of test1, test2 is still tested, and same with test3. Every test is independent of every other test. In the case of the nested if, if test1 is true, then the statements in the following block are executed, and then the entire block exits. The remaining tests are never executed—test2 is only executed if test1 is false, and test3 is executed only if both test1 and test2 are false.

In some cases, you might want separate, independent if statements, but in a lot of cases, you can group your tests in nested ifs instead.

If you're familiar with other languages, you might know switch or case statements that shorten nested ifs into a simpler syntax. Perl doesn't have syntax for switch, per se (it's probably the only instance you'll find where Perl doesn't provide a syntax to do something you can do in another language). However, there are various ways to use existing Perl constructs to build switch-like constructs. We'll go over a couple of these in “Going Deeper,” at the end of this lesson.

unless

The unless statement is sort of the reverse of an if. It came about because sometimes an operation is only supposed to occur if a test is false—which means in a standard ifelse statement, all the good stuff would go into the else, like this:

if ( test ) {
   # do nothing
} else {
   # the good stuff
}

That's not really the most optimal way to look at an if. You could, of course, just negate the test (!test or not test), and then switch the blocks and leave off the else. This is a classic case of having to change your thinking to fit the syntax. Perl would prefer that you think the way you want to think, so it gives you alternative syntax. If you want to perform an operation based a test being false, just use unless instead:

unless ( test ) {
   # the good stuff
}

With the unless here, the statements inside the block are only evaluated if the test is false (“unless this is true, do that”) If it's true, execution happily moves onto the next statement. You can also add an else to an unless, if you like (but you can't have an elsif).

Conditional Operator ?..:

Some conditionals are so short that it seems silly to waste all those brackets and words on them. Sometimes, too, it makes sense to embed a conditional inside another expression (something you can't do with an if or an unless because they don't return values). That's what the conditional operator does. Like ifelse, it has a test, something to do if the test is true, and something to do if the test is false:

test ? true_thing : false_thing;

Here, the test is evaluated for truth, just as with an if, and if the test is true the true_thing expression is evaluated (and a value returned), otherwise, false_thing is evaluated and returned. Unlike if and unless, true_thing, and false_thing are single expressions, not blocks. So, for example, a quick way to find the maximum of two values might look like this:

$max = $x > $y ? $x : $y;

This expression tests to see if the value of $x is larger than that of $y, and if so, it returns $x. If the value of $x is less than or equal to $y it returns $y. The return value of the entire conditional expression is then finally assigned to the $max variable. That same operation, as an ifelse, would look like this:

if ($x > $y) {
   $max = $x;
} else {
   $max = $y;
}

Note

The conditional operator is sometimes called the ternary operator because it has three operands (unary operators have one, binary operators have two; therefore, a ternary operator has three). Will knowing this impress anyone except computer scientists? Probably not.


Using Logical Operators as Conditionals

Back on Day 2, you learned about Perl's logical operators &&, ||, and, and or, and I mentioned at that time you can construct conditional statements with them. Let's reexamine those operators here so you can get a feel for how this works. Take the following expression:

$val = $this || $that;

To understand how this expression works, you have to remember two features of logical expressions: short-circuiting, and the fact that logicals return the value of the last thing they evaluated. So, in this case, the left side of the || is evaluated for its truth value. One of three things happens:

  • If the value of $this is anything other than 0 or "", it's considered true. Because the || operator short-circuits, this means the entire expression exits without even looking at $that. It also returns the last thing it did evaluate—the value of $this, which then gets assigned to the variable $val.

  • If the value of $this is 0 or "", it's considered false. Perl then evaluates $that, and if $that is true, then the expression exits with a truth value and returns the thing that it evaluated last—$that.

  • If both $this and $that are false, the entire expression returns false, and $val gets a 0 or "" value.

Note

You could, of course, use the or operator in place of the ||. Either one would work.


Using an ifelse expression, you could write that expression like this:

if ($this) { $val = $this; }
else {$val = $that; }

Using a conditional operator, you could write it like this:

$val = $this ? $this : $that

But both of those take more space and are sort of complex to figure out-or at least more complex than the logical expression, which reads sort of like English: this or that. There, you're done.

As I mentioned on Day 2, probably the most common place you'll see logicals used as conditionals is when you open files, like this:

open(FILE, "filename") or die "Can't open
";

But that's a topic for another day (Day 15, “Managing I/O,” to be exact).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset