Perl字符串if /或比较运算符

时间:2019-03-14 12:38:50

标签: perl if-statement operators conditional-statements

为什么下面的代码:

# Get new_status
print STDERR "Please enter status value (active/inactive): ";
ReadMode(1);
my $new_status = ReadLine(0);
ReadMode(0);
print STDERR "\n";

if ( ($new_status ne "active") || ($new_status ne "inactive") )
{
  die "Status must be active/inactive.";
}

将始终返回“状态必须为活动/非活动状态”。无论我键入什么? (有效,无效或其他任何方法,甚至只需按Enter键即可。)

该代码似乎有效:

  • 我清楚地用括号将这两个陈述分开
  • 我使用字符串 两种情况下都为“ ne”运算符
  • 我使用OR运算符||

我显然不完全了解Perl运算符。 我在做什么错了?

谢谢!

4 个答案:

答案 0 :(得分:2)

$new_status不能同时等于activeinactive,因此条件始终为true。您可能需要&&而不是||

选择任何看起来更直观的选项:

# option 1
if ( ($new_status ne "active") && ($new_status ne "inactive") )
...
# option 2
unless ( ($new_status eq "active") || ($new_status eq "inactive") )
...
#option 3
my %VALID_STATUS = (
    'active' => 1,
    'inactive' => 1,
);
if (!$VALID_STATUS{$new_status})
...

答案 1 :(得分:2)

if ( ($new_status ne "active") || ($new_status ne "inactive") )
{
  die "Status must be active/inactive.";
}

让我们通过逻辑来工作。

  1. 我输入的内容是随机的(让我们使用random)。 random不是“活动”也不是“非活动”,因此您的if子句变为if (true or true)-是的。
  2. 我输入active。第一次检查是错误的,第二次检查是正确的,因此您得到if (false or true)-是的。
  3. 我输入inactive。第一次检查是正确的,第二次检查是false,因此您得到if (true or false)-是正确的。

您无法输入任何使您的if语句为假的信息。

您不想将两个子句与or联接在一起的问题,应该改用and

(并从这位老程序员那里获得一些技巧-使用andor而不是&&||进行流控制将大大减少混乱。)

更新:总而言之,您的代码中包含太多否定词,您对此感到困惑。在您的答案中,您(无声!)将if更改为unless,从而使维护程序员更难以遵循该代码。

我会这样写:

my $valid = $new_status eq 'active' || $new_status eq 'inactive';
if (not $valid) {
   die "...";
}

或者这样:

use List::Util 'any';

if (not any { $new_status eq $_ } qw[active inactive] ) {
  die "...";
}

答案 2 :(得分:2)

您只想在$new_status不是active的情况下显示错误消息,而在$new_status不是inactive的情况下显示,所以< / p>

if ( $new_status ne "active" || $new_status ne "inactive" )

应该是

if ( $new_status ne "active" && $new_status ne "inactive" )

我们可以证明这一点。记住De Morgan's laws

  • !( A || B )等同于!A && !B
  • !( A && B )等同于!A || !B

所以

  • 有效输入,如果$new_status eq 'active' || $new_status eq 'inactive'
  • 如果!( $new_status eq 'active' || $new_status eq 'inactive' )
  • ,则输入无效
  • 如果!( $new_status eq 'active' ) && !( $new_status eq 'inactive' )
  • ,则输入无效
  • 如果$new_status ne 'active' && $new_status ne 'inactive'
  • ,则输入无效

您将需要习惯于看到以下内容:

if ( $new_status ne "active" && $new_status ne "inactive" ) {
   die("Status must be active/inactive.\n");
}

但是您可能更喜欢使用断言的编码方式。

$new_status eq "active" || $new_status eq "inactive"    # Thing that should be true.
   or die("Status must be active/inactive.\n");         # Or what to do when it isn't.

答案 3 :(得分:-5)

所以我找到了问题的答案。

问题出在格式化上。

我添加了:

print Dumper $new_status;

在我的代码中,输出为:

$VAR1 = 'active
';

所以我添加了一个:

chomp $new_status;

现在可以正常运行了。

$VAR1 = 'active';

最终代码:

# Get new_status
print STDERR "Please enter status value (active/inactive): ";
ReadMode(1);
my $new_status = ReadLine(0);
ReadMode(0);
print STDERR "\n";

chomp $new_status;

unless ( ($new_status eq "active") || ($new_status eq "inactive") )
{
  die "Status must be active/inactive.";
}