Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Confused by a Conditional

by nysus (Deacon)
on Jun 09, 2001 at 21:09 UTC ( #87201=perlquestion: print w/ replies, xml ) Need Help??
nysus has asked for the wisdom of the Perl Monks concerning the following question:

Arrggh! Someone please bail me out of my newbie misery.
#!/usr/bin/perl -w use strict; my $key = 'JUMP'; if ($key eq 'ID' or 'TITLE' or 'GENE' or 'CYTOBAND' or 'LOCUSLINK' or +'CHROMOSOME' or 'SCOUNT') { print "I don't know why this is printing.\n"; }
Why is the above conditional coming out as true?????????

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar";
$nysus = $PM . $MCF;

Comment on Confused by a Conditional
Download Code
(ar0n) Re: Confused by a Conditional
by ar0n (Priest) on Jun 09, 2001 at 21:15 UTC
    Because strings are true. You're checking to see if $key is 'ID', or if 'TITLE' is true, or if 'GENE' is true, etc. string constants are always true.

    I think you're trying to see if $key is one of those strings. In that case, you could use:
    if ( grep { $key eq $_ } qw(ID TITLE GENE CYTOBAND LOCUSLINK CHROMOSOM +E SCOUNT) ) { # do your stuff }
    ... which will check to see if $key matches at least one of those.

    ar0n ]

Re: Confused by a Conditional
by KM (Priest) on Jun 09, 2001 at 21:15 UTC
    Because the following are considered true:

    'TITLE' or 'GENE' or 'CYTOBAND' or 'LOCUSLINK' or 'CHROMOSOME' or 'SCO +UNT'

    You will want to repeat the $key eq 'something' bit, or have possible matches in a pattern match a la /(TITLE|GENE|CYTOBAND|etc..)/, or have the possible matches in an array and grep through it (perldoc -f grep), or in a hash and do one if exists $hash{$key}....

    Cheers,
    KM

Re: Confused by a Conditional
by wog (Curate) on Jun 09, 2001 at 21:16 UTC
    The reason the conditional is coming out as true is that it is not parsed the way you think it is:

    if ( ($key eq 'ID') or 'TITLE' or 'GENE' or 'CYTOBAND' or 'LOCUSLINK' or 'CHROMOSOME' or 'SCOUNT') # ... }

    ... is the same thing. The strings 'TITLE', etc. are considered true by perl.

    (update: ... and everyone beats me and gives better answers. Sigh...)

Re (tilly) 1: Confused by a Conditional
by tilly (Archbishop) on Jun 09, 2001 at 21:17 UTC
    It is parsed like this:
    #!/usr/bin/perl -w use strict; my $key = 'JUMP'; if ( ($key eq 'ID') or ('TITLE') or ('GENE') or ('CYTOBAND') or ('LOCUSLINK') or ('CHROMOSOME') or ('SCOUNT') ) { print "I don't know why this is printing.\n"; }
    and the chain of or's is broken at the first true statement. Namely 'TITLE'. You need to put a lot more "$key eq" statements in there.

    The other common options are:

    if (grep {$key eq $_} qw(ID TITLE GENE CYTOBAND LOCUSLINK CHROMOSOME S +COUNT)) { print "This didn't print, did it?\n"; }
    or put the list in a hash and write the test as:
    if (exists $is_valid{$key}) { print "Key '$key' is a valid key\n"; }
Re: Confused by a Conditional
by princepawn (Parson) on Jun 09, 2001 at 21:31 UTC
    this looks like a job for Switch
(zdog) Re: Confused by a Conditional
by zdog (Priest) on Jun 09, 2001 at 21:58 UTC
    Here's another way of doing it in addition to the ones already mentioned:

    if (' ID TITLE GENE CYTOBAND LOCUSLINK CHROMOSOME SCOUNT ' =~ m/ $key +/) { print "stuff.\n"; }

    NOTE: The spaces in this solution are key in making sure the right word is being matched.

    Zenon Zabinski | zdog | zdog7@hotmail.com

      Note that if $key is a user-provided value, doing this is not a good idea. At the very least you would want to enclose the whole thing in an eval in case $key contains some characters that upset the match operator (for example, if $key contains **, the program will die with "nested *?+ in regexp"). In the worst case, $key could contain something that makes Perl execute arbitrary code. So for doing something like this, you have to make sure that $key is properly untainted.

      Update: You could also use \Q, as in "string" =~ m/ \Q$key /

      --ZZamboni

Re: Confused by a Conditional
by AgentM (Curate) on Jun 10, 2001 at 00:06 UTC
Re: Confused by a Conditional
by damian1301 (Curate) on Jun 10, 2001 at 10:27 UTC
    delete

    Tiptoeing up to a Perl hacker.
    Dave AKA damian

      I admit, that's pretty cool. But I personally like this just a bit better (only because it takes up less space on the line):

      #!/usr/bin/perl -w use strict; my $key = 'JUMP'; if ($key =~ /^(ID|TITLE|GENE|CYTOBAND|LOCUSLINK|CHROMOSOME|SCOUNT)$/) +{ print "I don't know why this is printing.\n"; }

      I think there's someway that might be broken, though, if I remember my reading on regexes... but if you chomp everything right, I think it will accomplish the same thing (with the added benefit(?) of placing exactly what it matched in $1).

      CheeseLord

      You are very, very wrong.
      'ID' or 'TITLE' or 'GENE' or 'CYTOBAND' or 'LOCUSLINK' or 'CHROMOSOME' or 'SCOUNT'
      evaluates to 'ID'.
      use strict; my $key = 'TITLE'; unless (($key) eq ('ID' or 'TITLE' or 'GENE' or 'CYTOBAND' or 'LOCUSLINK' or 'CHROMOSOME' or 'SCOUNT')) { print "Damian is wrong\n"; }
      This prints "Damian is wrong".

      -- Abigail

        delete

        Tiptoeing up to a Perl hacker.
        Dave AKA damian

      The only way the conditional in your snippet evaluates to true is if $key=='ID'. Try setting $key to 'GENE', for example (which is one of the valid values), and you'll see.

      --ZZamboni

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://87201]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (13)
As of 2015-07-06 13:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (74 votes), past polls