SAAS saas._._
SAAS saas._._

Reputation: 13

If with and / || / && in perl

I'm trying to see if the user is using the correct letters in perl, but it doesn't work that way

chop($reply = <STDIN>);

if($reply ne "a" || $reply ne "b" || $reply ne "c" || $reply ne "d") {print " !!! ERROR !!!\n";}

Upvotes: 1

Views: 147

Answers (2)

simbabque
simbabque

Reputation: 54323

Your logic is flawed. Your condition is always true, because "a" ne "b" is always true. It doesn't matter which one of the allowed letters you enter, the other ones will always fail.

There are several ways to rewrite this condition.

The most verbose is to use logical and rather than or. You want this condition:

The input is not A and the input is not B and the input is not C and the input is not D.

if (  $reply ne "a"
   && $reply ne "b"
   && $reply ne "c"
   && $reply ne "d" ) { ... }

If you want it a lot less verbose, you can use a pattern match instead. This tests if the string does not match the pattern, which is exactly one of the four letters given in the character group. The group can also be written with a range as [a-d].

if ( $reply !~ m/^[abcd]$/ ) { ... }

Finally, if there are more options or the options are more complex, you could make a dispatch table using a hash. This is much more advanced, but could be combined with subroutine references. There's a chapter about them in Higher Order Perl.

You create a hash with the values that you want to allow as keys, and you can then use exists to check if that value is allowed.


my %allowed = ( 
  a => 1, 
  b => 1, 
  c => 1, 
  d => 1,
);

if ( !exists $allowed{$reply} ) { ... }

Upvotes: 6

Tom Williams
Tom Williams

Reputation: 203

You may want to test against a regular expression instead, if you've learned about them yet:

chomp ($reply=<STDIN>);
if ($reply !~/^[a-d]$/) {print 'Error'} 

Upvotes: 0

Related Questions