Section 10.3.  Expression Modifiers

Table of Contents

10.3. Expression Modifiers

For a more compact notation, an expression may be followed by a modifier that controls it. For example, the if modifier works in a way analogous to an if block:

    print "$n is a negative number.\n" if $n < 0;

That gives the same result as if we had used this code, except that we saved some typing by leaving out the parentheses and curly braces:[*]

[*] We also left out the line breaks. But we should mention that the curly-brace form does create a new scope. In the rare case that you need the full details, check the documentation.

    if ($n < 0) {
      print "$n is a negative number.\n";

Perl folks generally like to avoid typing. The shorter form reads like in English: print this message if $n is less than zero.

The conditional expression is still evaluated first, even though it's written at the end. This is backward from the usual left-to-right ordering. In understanding Perl code, you'll have to do as Perl's internal compiler does, and read to the end of the statement before you can tell what it's doing.

There are other modifiers as well:

    &error("Invalid input") unless &valid($input);
    $i *= 2 until $i > $j;
    print " ", ($n += 2) while $n < 10;
    &greet($_) foreach @person;

These work as you would expect (we hope). Each one could be rewritten in a similar way to rewriting the if-modifier example earlier. Here is one:

    while ($n < 10) {
      print " ", ($n += 2);

The expression in parentheses inside the print argument list is noteworthy because it adds two to $n, storing the result back into $n. Then, it returns that new value, which will be printed.

These shorter forms read almost like a natural language: call the &greet subroutine for each @person in the list. Double $i until it's larger than $j.[Section 10.3.  Expression Modifiers] One of the common uses of these modifiers is in a statement like this one:

[Section 10.3.  Expression Modifiers] Well, it helps us to think of them like that.

    print "fred is '$fred', barney is '$barney'\n"           if $I_am_curious;

By writing the code "in reverse," you can put the important part of the statement at the beginning. The point of that statement is to monitor some variables; the point is not to check if you're curious.[*] Some people prefer to write the whole statement on one line, perhaps with some tab characters before the if, to move it over toward the right margin as we showed in the previous example. Others put the if modifier indented on a new line:

[*] We made up the name $I_am_curious; it's not a built-in Perl variable. Generally, folks who use this technique will call their variable $TRACING or use a constant declared with the constant pragma.

    print "fred is '$fred', barney is '$barney'\n"
        if $I_am_curious;

Though you can rewrite any of these expressions with modifiers as a block (the "old-fashioned" way), the converse isn't necessarily true. Only a single expression is allowed on either side of the modifier. You can't write something if something while something until something unless something foreach something, which would be too confusing anyway. And you can't put multiple statements on the left of the modifier. If you need more than one expression on each side, write the code the old-fashioned way, with the parentheses and curly braces.

As we mentioned in relation to the if modifier, the control expression (on the right) is evaluated first as it would be in the old-fashioned form.

With the foreach modifier, there's no way to choose a different control variableit's always $_. Usually, that's no problem, but if you want to use a different variable, you'll need to rewrite it as a traditional foreach loop.

    Table of Contents
    © 2000- NIV