hasimir44 has asked for the wisdom of the Perl Monks concerning the following question:

Does perl work like shell scripting when using && and || or is there a different/better way? ex:

if (($val > 5) && ($val < 10)) { ... }

I'm going through "Learning Perl" right now at a cafe and I'm stubbornly concerned with this.. I can't find an example in the book or on google.. weird. Anyway, thanks..

Replies are listed 'Best First'.
by Tanktalus (Canon) on May 14, 2006 at 04:59 UTC

    I'm not sure what you mean "like shell scripting"... Conceptually, they're the same idea, although their implementation details are incredibly different.

    Your example, if (($val > 5) && ($val < 10)) { ... } probably does what you expect: execute the "..." part if $val is numerically between 5 and 10, exclusive.


    • The extra parenthesis aren't needed. They don't hurt, either. i.e., if ($val > 5 && $val < 10) { ... } is fine.
    • && can be written and. Conceptually, these two operators do the same thing, but they are distinct for a reason: they have different precedence. So they're not completely interchangeable. Though, in if-clauses such as this, they usually are interchangeable.
    • I find it a wee bit more readable to follow numbers from left to right in increasing values. e.g., if (5 < $val and $val < 10) { ... } This just seems more natural to me as a human reader, even though it doesn't seem natural to most programmers who have learned that they need to break up the mathematical term "5 < V(x) < 10" or whatever into two distinct tests.
    Just my 2 cents CDN.

      That's exactly what I wanted. Thanks for the detail. Perl is cooler than river dancing.
by Zaxo (Archbishop) on May 14, 2006 at 06:14 UTC

    Additional to what Tanktalus said.

    The logical operator pairs (&& and), and (|| or) only differ by their precedence. The spelled-out ones have extremely low precedence, while the symbolic ones are fairly high.

    These operators are "lazy evaluated". The or op will not evaluate its right-hand term if the left evaluated true. The and op will not evaluate its right-hand term if the left evaluated false. That makes the following possible.

    The logical operators can be used as concise forms of program flow control. That is often seen in error handling. An operation which returns true on success will skip an operation connected by or, so we write,

    open my $fh, '<', $filename or die $!;
    to handle failure to open a file, for example.

    After Compline,

by graff (Chancellor) on May 14, 2006 at 06:22 UTC
    Another similarity between perl and shell (common to C as well), is that the second expression will not be evaluated at all if the first expression "answers the question". This matters when the second expression has side effects. Some trivial examples:
    sub f0 { return 0 } sub f1 { return 1 } if (( my $x = f1() ) && ( my $y = f1() )) # true, and both variables are set to 1 if (( my $x = f0() ) && ( my $y = f1() )) # false, $x is set to 0, $y is undef if (( my $x = f0() ) || ( my $y = f1() )) # true, $x is set to 0, $y is set to 1 if (( my $x = f1() ) || ( my $y = f1() )) # true, $x is set to 1, $y is undef
    As in shell usage, this can be used to good effect, to perform (or skip) an action based on the outcome of previous action. (It can also be a trap for the unwary.)
      (for keyword or further-search purposes) that behavior is dubbed "short-circuiting"

      And i'll toss in a good C example (avoid method calls on undef/null):
      int *x; if(ptr != NULL && *ptr==5){ ... } if( objPtr != NULL && objPtr->foo() ){ ... } # extended to perl: my $obj = Foo::Bar->new(); if( $obj && $obj->blah() ){ ... }
      Update: added parens for ->foo()

        Heh, you hit a C pet peave of mine. This:

        if( objPtr != NULL && objPtr->foo ){ ... }

        doesn't actually call any methods. You need objPtr->foo() for that. And the ANSI C committee should have made the "&" for getting a pointer to a method mandatory instead of optional and discouraged, as needing to do that is relatively rare, rarer than the mistake of not realizing that C requires the parens unlike several other quite similar languages. Further, this particular mistake usually results in compiler output that is quite difficult to diagnose, IME.

        - tye        

by ioannis (Abbot) on May 14, 2006 at 05:18 UTC
    Also, the vim editor will color the operators and, or, but will not highlight the && operator; long expressions become easier to read.