http://qs321.pair.com?node_id=775463

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

Hello monks!
is there a quick way to write the conditionals:
If $string is not X and $string is not Y
instead of typing:
if($string ne 'Y' && $string ne 'Y')
? Also, a quick way to say:
If $string is A or $string is B
instead of:
if($string eq 'A' or $string eq 'B')
?
Thank you!

2009-06-28 Retitled by GrandFather, as per Monastery guidelines

Replies are listed 'Best First'.
Re: conditional syntax options
by citromatik (Curate) on Jun 28, 2009 at 14:30 UTC

    The code you provide is clear and concise enough, I would stay with it. But, just for curiosity, since Perl 5.10 you can use the smart-match (~~) operator for a shorter alternative (see perlop):

    • if (! $string ~~ qw/A B/)
    • if ($string ~~ qw/A B/)
    • citromatik

Re: conditional syntax options
by ELISHEVA (Prior) on Jun 28, 2009 at 14:25 UTC

    Not sure what you mean by "quick". Do you want an equally succint, but more "English" way of expressing conditions? Or do you want to type even fewer characters than the expressions you have already provided?

    If "even shorter" is your goal, then I'm afraid you would lose clarity. Though some golf expert is sure to point the way to "even shorter", I wouldn't use that in production code.

    If "just as short but more English" is the goal, then I would say, your question is a little like asking "Is there a fast way to say 'Je ne sais pas' in French, without actually saying 'Je ne sais pas'?" Every language, even a programming language, has its idiom. The expressions you have written are the idiom of Perl, as much as 'Je ne sais pas' is the idiom of French.

    Best of luck and welcome to Perl Monks (and Perl), beth

    Update:Citromatik saw an angle to your question that I missed. In the spirit of Citromatik's answer below, a pre-Perl 5.10 equivalent is if ($string =~ /^(?:A|B)$/). if ($string =~ /^(?:A|B)\z/).To compare $string to the strings A,B,C,D you can do $string =~ /^(?:A|B|C|D)$/ $string =~ /^(?:A|B|C|D)\z/ and so forth. But I think the syntax that you have chosen in your post is much more readable unless you have a long list of strings to which you want to compare $string

    Update: as per Kyle.

      A /$/ will match a newline as well as end-of-string. To match a literal end-of-string, use /\z/ instead.

Re: conditional syntax options
by mzedeler (Pilgrim) on Jun 28, 2009 at 16:12 UTC

    If you want to check against a lot of constants, you can grep:

    if(not grep {$string eq $_} qw{ X Y })

    You can extend the list with X and Y as much as you like. Using it on two values only is overkill.

      That was my thought as well, but as citromatik points out, Perl 5.10's ~~ is a very good option, even better in fact!

      --
      I'd like to be able to assign to an luser