如何在Perl中使用布尔变量?


220

我努力了:

$var = false;
$var = FALSE;
$var = False;

这些都不起作用。我收到错误消息

使用“ strict subs”时,不允许使用“ false”标头。

37
您可能想从我的书Learning Perl开始。这比猜测正确的方法要容易得多,直到正确为止(猴子,打字机,哈姆雷特等等)。:)
brian d foy

Answers:


285

在Perl中,以下条件在条件中评估为false:

0
'0'
undef
''  # Empty scalar
()  # Empty list
('')

其余的都是真的。没有针对true或的裸词false


2
@BlueWaldo:在比较并将比较结果分配给标量时,也可以使用cmp和<=>。$ var = $ var1 cmp $ var2; 如果左参数小于,等于或大于右参数,则'cmp'和'<=>'(用于数字比较)将返回-1、0或1。它不是布尔值,但有时您可能想知道一个参数ir是否等于或小于另一个参数,而不是等于或不等于。
user118435

9
问题1:空列表不是虚假的,因为不可能检查列表是真还是假。标量上下文中的空列表返回undef
ikegami

4
问题2:('')''是相同的值。我想您想暗示一个包含一个由空字符串组成的元素的列表(即使parens不会创建列表),但是正如我已经提到的,无法检查列表是否为false。
ikegami

6
问题3:具有布尔运算符重载的对象也可能为假。
ikegami

15
@ eternicode,Perl在需要返回true和false时确实使用了两个特定值,因此它不仅具有布尔值,还具有true(!0aka PL_sv_yes)和false(!1aka PL_sv_no)。还是您说只要测试了这两个值以外的其他因素,Perl就应该哭泣?那将是完全可怕的。例如,它将防止$x ||= $default;
ikegami 2012年

71

我遇到的关于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"

如果我理解你的权利的话真正虽然那个字符串化到0的数字是真实的应该是假的或(防止混淆)评估为假
user907860

1
您的“简洁”定义与您更长的解释不一致。考虑:my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };。现在$value将字符串化为“ XXX”,但布尔值化为false。
tobyink 2014年

1
@tobyink,简洁的版本不是完美的,仅仅是我发现的最好的版本。这意味着实用,而不是无所不包。请注意,您的返回值bool确实会字符串化为0。同样,不鼓励您创建不一致的重载,并且您返回的值也可以认为是这样。(例如,&&可以将a优化为||,因此,如果它们不一致,则可能会有问题。)
ikegami 2014年

我不确定0x00这里是否覆盖了。
Zaid 2014年

@Zaid,您的意思是代码返回的值0x00(数值为零)还是字符串0x00(其looks_like_number值为false)?无论哪种方式,它都已经涵盖了。
ikegami 2015年

59

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中非常常见的混淆源。


5
use warnings;而不是#! perl -w
布拉德·吉尔伯特

11
用常量作为穷人宏会很危险。这些代码示例并不等效:if ($exitstatus) { exit; }vs if ($exitstatus == true) { exit; },这对偶然的观察者可能并不明显。(是的,最后一个例子是不良的编程风格,但这是无关紧要的)。
Zano

16

我推荐use boolean;。您必须从cpan 安装boolean模块。


7
在Perl中,就像在生活中一样,有许多真理。没有经验的人喜欢写傻的东西if ($my_true_value == true)。根据我的经验,假装有一个真相,这是通往痛苦和低效代码的道路。
tjd 2014年

2
Perl本质上是哲学的
ILMostro_7'1

13

我的最爱一直是

use constant FALSE => 1==0;
use constant TRUE => not FALSE;

这完全独立于内部表示。


5
辉煌。您已经一手解决了Perl编程语言!
Nostalg.io

8

我遇到了一个教程,其中对Perl中的正确和错误值进行了很好的解释。它指出:

以下标量值被认为是错误的:

  • undef -未定义的值
  • 0 数字0,即使将其写为000或0.0
  • '' 空字符串。
  • '0' 包含一个0位数的字符串。

所有其他标量值,包括以下各项均为真:

  • 1 任何非0的数字
  • ' ' 带有空格的字符串
  • '00' 字符串中两个或多个0字符
  • "0\n" 0后跟换行符
  • 'true'
  • 'false' 是的,即使字符串“ false”也计算为true。

还有另一本很好的教程介绍了Perl true和false


6

bobf对布尔值给出了漂亮的解释:对 还是?快速参考指南

不同值的真相测试

                       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

答案很差,但在perlmonks.org上却是可靠的可靠来源。最好有一些真实的内容,而不是评论和链接。:-/
ILMostro_7

0

使用以下文件前缀,这将添加到您的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用作键的值,但是这种破解将确保脚本中保留正确的值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.