为什么下面的代码:
# 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键即可。)
该代码似乎有效:
我显然不完全了解Perl运算符。 我在做什么错了?
谢谢!
答案 0 :(得分:2)
$new_status
不能同时等于active
和inactive
,因此条件始终为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.";
}
让我们通过逻辑来工作。
random
)。 random
不是“活动”也不是“非活动”,因此您的if
子句变为if (true or true)
-是的。active
。第一次检查是错误的,第二次检查是正确的,因此您得到if (false or true)
-是的。inactive
。第一次检查是正确的,第二次检查是false,因此您得到if (true or false)
-是正确的。您无法输入任何使您的if
语句为假的信息。
您不想将两个子句与or
联接在一起的问题,应该改用and
。
(并从这位老程序员那里获得一些技巧-使用and
和or
而不是&&
和||
进行流控制将大大减少混乱。)>
更新:总而言之,您的代码中包含太多否定词,您对此感到困惑。在您的答案中,您(无声!)将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.";
}