Carl Mäsak wrote:

> Do not combine 'ne' and '|', like this:
> 
> die "Unrecognized directive: TMPL_$directive"
>    if $directive ne 'VAR' | 'LOOP' | 'IF';

> One is tempted to assume that this means the same as "$directive ne
> 'VAR' || $directive ne 'LOOP' || $directive ne 'IF"", but it doesn't.
> Instead, it's a negated string comparison against three values, the
> results of which are then OR-ed together. The condition will always be
> true, because there's always at least two values that $directive is
> not string-equal to.

        $directive ne 'VAR' || $directive ne 'LOOP' || $directive ne 'IF'

is always true.  For example assuming $directive = "cat";

        "cat" ne 'VAR' (true) || "cat" ne 'LOOP' (true) || "cat" ne 'IF' (true)

or assuming $directive = "VAR";   Then:

        "VAR" ne 'VAR" (false) || "VAR" ne 'LOOP' (true) || "VAR" ne 'IF' (true)

which is clearly not what you wanted.  This works if you write instead:

        $directive ne 'VAR' && $directive ne 'LOOP' && $directive ne 'IF'

        "VAR" ne 'VAR" (false) && "VAR" ne 'LOOP' (true) && "VAR" ne 'IF' (true)

Result: false.   (if it is not one of these things.... then....)

Of course now I'm confused as to what:   $directive ne 'VAR' | 'LOOP' | 'IF'
does.  If it was equivalent to:

        not ($directive eq 'VAR' || $directive eq 'LOOP' || $directive eq 'IF')

then it would be doing the right thing.  So since it isn't doing the right
thing, I can only assume that your statement above is in error and that:

        $directive ne 'VAR' | 'LOOP' | 'IF'

IS INDEED the same as:

        $directive ne 'VAR' || $directive ne 'LOOP' || $directive ne 'IF'

and that your expectation of the code is wrong.

> The "correct" form using junctions would be this:
> 
> die "Unrecognized directive: TMPL_$directive"
>    if $directive ne 'VAR' & 'LOOP' & 'IF';

which makes sense, because this does give us:

        $directive ne 'VAR' && $directive ne 'LOOP' && $directive ne 'IF'

and that is provably correct.

> The more general advice, then, would be not to use junctions together
> with negated equality operators. Instead, use the non-negated equality
> operator, and negate the whole expression.

This is probably a good idea regardless,

        J

-- 
   ("`-''-/").___..--''"`-._          |  Jacinta Richardson         |
    `6_ 6  )   `-.  (     ).`-.__.`)  |  Perl Training Australia    |
    (_Y_.)'  ._   )  `._ `. ``-..-'   |      +61 3 9354 6001        |
  _..`--'_..-_/  /--'_.' ,'           | [EMAIL PROTECTED] |
 (il),-''  (li),'  ((!.-'             |   www.perltraining.com.au   |

Reply via email to