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

问题描述 投票:-3回答:4

为什么是以下代码:

# 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运算符的东西我还没有完全掌握。我究竟做错了什么?

谢谢 !

perl if-statement operators condition
4个回答
2
投票

$new_status不能同时与activeinactive相等,所以条件总是如此。你可能需要&&而不是||

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

# 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})
...

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。这在第一次检查时是正确的,在第二次检查时是假的,所以你得到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
投票

您只想显示错误消息,如果$new_status不是active并且如果$new_status不是inactive,那么

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.

-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.";
}
© www.soinside.com 2019 - 2024. All rights reserved.