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

I'm using the short version of the if statement and have a little problem (when I use the long version: if - else, it works). when doing:
for (values(%{$hash})) { /yes/i ? $_ = 'Yes' : $_ = 'No'; }
on $hash which it's value's are YES or NO (all capital), I get all the values (after the loop) to be NO (all capital) no matter if I had YES values (and it's also 'NO' and not 'No'). Can someone tell me what the hell is going on here?

Thanks

Hotshot

Replies are listed 'Best First'.
Re: if condition problem
by fglock (Vicar) on Sep 19, 2002 at 17:45 UTC
    /yes/i ? ($_ = 'Yes') : ($_ = 'No');

    should do it. It's because "=" has higher precedence than "?:" (see perldoc perlop). This should also work:

    $_ = /yes/i ? 'Yes' : 'No';

    update: The  ?: is called the  conditional operator. It is a  ternary operator because it has 3 arguments.

Re: if condition problem
by Django (Pilgrim) on Sep 19, 2002 at 18:32 UTC

    "I'm using the short version of the if statement"

    The trinary operator does not work exactly like an if statement, thus it's no short version of it.
    Here are some differences:

    $_ = # one statement /yes/i # conditional expression ? 'Yes' # value if cond==true : 'No' # 'else' value ; if (/yes/i) # control structure { $_='Yes' } # block is run if cond==true else { $_='No' } # 'else' block (scope!)
    The trinary operator is a logical operator, not a control structure.

    ~Django
    "Why don't we ever challenge the spherical earth theory?"

Re: if condition problem
by Nemp (Pilgrim) on Sep 19, 2002 at 17:47 UTC
    Update: Looks like I was a little slow off the mark to fglock here :)

    You have a problem with the precedence of the trinary operator as compared to the = I believe.

    Adding brackets will help you no end :) Like this...
    for (values(%{$hash})) { /yes/i ? ($_ = 'Yes') : ($_ = 'No'); }
    HTH,
    Neil
Re: if condition problem
by sauoq (Abbot) on Sep 19, 2002 at 20:19 UTC

    As fglock pointed out, $_ = /yes/i ? 'Yes' : 'No'; will work. I'll go a step further and say it is preferred. Returning one value or another dependent on a given condition is exactly what ?: is meant to do. It is not meant to be a short version of an if-statement.

    As an aside, you might want to be a little more cautious with your regular expression. The string 'noyes' will become 'Yes' with the way you are currently doing it. Consider anchoring the pattern to the beginning of the line like: /^yes/i; to avoid an error like that. Anchor it to both ends with /^yes$/ if want to avoid something like 'yesno' being interpretted as 'Yes' as well.

    -sauoq
    "My two cents aren't worth a dime.";