Answers:
在Perl中,以下条件在条件中评估为false:
0
'0'
undef
'' # Empty scalar
() # Empty list
('')
其余的都是真的。没有针对true
或的裸词false
。
undef
。
('')
和''
是相同的值。我想您想暗示一个包含一个由空字符串组成的元素的列表(即使parens不会创建列表),但是正如我已经提到的,无法检查列表是否为false。
!0
aka PL_sv_yes
)和false(!1
aka PL_sv_no
)。还是您说只要测试了这两个值以外的其他因素,Perl就应该哭泣?那将是完全可怕的。例如,它将防止$x ||= $default;
我遇到的关于false的最完整,简洁的定义是:
字符串化为空字符串或字符串的任何内容
0
均为false。其他一切都是真的。
因此,以下值为false:
请记住,在标量上下文中,空列表文字的计算结果为未定义的值,因此其计算结果为false。
关于“真零”的注释
0
字符串化为假的数字是错误的,而字符串化为零的字符串则不一定。唯一的错误字符串是0
和空字符串。任何其他字符串,即使它的数值为零,也都为true。
以下是布尔值为true且数字为零的字符串:
"0.0"
"0E0"
"00"
"+0"
"-0"
" 0"
"0\n"
".0"
"0."
"0 but true"
"\t00"
"\n0e1"
"+0.e-9"
Scalar::Util::looks_like_number
返回false的字符串。(例如"abc"
)my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };
。现在$value
将字符串化为“ XXX”,但布尔值化为false。
bool
确实会字符串化为0
。同样,不鼓励您创建不一致的重载,并且您返回的值也可以认为是这样。(例如,&&
可以将a优化为||
,因此,如果它们不一致,则可能会有问题。)
0x00
这里是否覆盖了。
0x00
(数值为零)还是字符串0x00
(其looks_like_number
值为false)?无论哪种方式,它都已经涵盖了。
Perl没有本地布尔类型,但是您可以使用整数或字符串的比较来获得相同的行为。艾伦(Alan)的例子是使用整数比较的一种好方法。这是一个例子
my $boolean = 0;
if ( $boolean ) {
print "$boolean evaluates to true\n";
} else {
print "$boolean evaluates to false\n";
}
我在某些程序中完成的一件事是使用常量添加了相同的行为:
#!/usr/bin/perl
use strict;
use warnings;
use constant false => 0;
use constant true => 1;
my $val1 = true;
my $val2 = false;
print $val1, " && ", $val2;
if ( $val1 && $val2 ) {
print " evaluates to true.\n";
} else {
print " evaluates to false.\n";
}
print $val1, " || ", $val2;
if ( $val1 || $val2 ) {
print " evaluates to true.\n";
} else {
print " evaluates to false.\n";
}
标记为“使用常量”的行定义了一个始终为1的名为true的常量和始终为0的一个名为false的常量。由于在Perl中定义了常量,因此以下代码行也会失败:
true = 0;
true = false;
错误消息应显示类似“无法在标量分配中修改常量”之类的内容。
在您询问的有关比较字符串的评论之一中,我看到了这一点。您应该知道,由于Perl在标量变量中组合了字符串和数字类型,因此您具有用于比较字符串和数字的不同语法:
my $var1 = "5.0";
my $var2 = "5";
print "using operator eq\n";
if ( $var1 eq $var2 ) {
print "$var1 and $var2 are equal!\n";
} else {
print "$var1 and $var2 are not equal!\n";
}
print "using operator ==\n";
if ( $var1 == $var2 ) {
print "$var1 and $var2 are equal!\n";
} else {
print "$var1 and $var2 are not equal!\n";
}
这些操作符之间的差异是Perl中非常常见的混淆源。
use warnings;
而不是#! perl -w
if ($exitstatus) { exit; }
vs if ($exitstatus == true) { exit; }
,这对偶然的观察者可能并不明显。(是的,最后一个例子是不良的编程风格,但这是无关紧要的)。
我推荐use boolean;
。您必须从cpan 安装boolean模块。
if ($my_true_value == true)
。根据我的经验,假装有一个真相,这是通往痛苦和低效代码的道路。
我的最爱一直是
use constant FALSE => 1==0;
use constant TRUE => not FALSE;
这完全独立于内部表示。
我遇到了一个教程,其中对Perl中的正确和错误值进行了很好的解释。它指出:
以下标量值被认为是错误的:
undef
-未定义的值0
数字0,即使将其写为000或0.0''
空字符串。'0'
包含一个0位数的字符串。所有其他标量值,包括以下各项均为真:
1
任何非0的数字' '
带有空格的字符串'00'
字符串中两个或多个0字符"0\n"
0后跟换行符'true'
'false'
是的,即使字符串“ false”也计算为true。还有另一本很好的教程介绍了Perl true和false。
不同值的真相测试
Result of the expression when $var is:
Expression | 1 | '0.0' | a string | 0 | empty str | undef
--------------------+--------+--------+----------+-------+-----------+-------
if( $var ) | true | true | true | false | false | false
if( defined $var ) | true | true | true | true | true | false
if( $var eq '' ) | false | false | false | false | true | true
if( $var == 0 ) | false | true | true | true | true | true
使用以下文件前缀,这将添加到您的perl脚本eTRUE和eFALSE,它实际上将是REAL(!)true和false(就像Java)
#!/usr/bin/perl
use strict;
use warnings;
use constant { #real true false, compatible with encode_json decode_json for later (we don't want field:false... will be field:0...)
eTRUE => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
eFALSE => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' )
};
实际上,没有什么理由可以使用它。
我的原因是使用JSON,我将0和1用作键的值,但是这种破解将确保脚本中保留正确的值。