Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Confused by a Conditional

by nysus (Parson)
on Jun 09, 2001 at 21:09 UTC ( [id://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;

Replies are listed 'Best First'.
(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 (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 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 AgentM (Curate) on Jun 10, 2001 at 00:06 UTC
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...)

(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 princepawn (Parson) on Jun 09, 2001 at 21:31 UTC
    this looks like a job for Switch
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

      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

      A reply falls below the community's threshold of quality. You may see it by logging in.
      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

        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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
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?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2024-04-16 06:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found