为什么Perl使用空字符串表示布尔值false?

前端之家收集整理的这篇文章主要介绍了为什么Perl使用空字符串表示布尔值false?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
当在标量(布尔)上下文中评估表达式时,如果表达式求值为true,则Perl将使用显式值1作为结果,如果表达式求值为false,则使用空字符串.
我很好奇为什么Perl使用空字符串来表示布尔值,而不是0,这似乎更直观.

请注意,我不关心Perl将空字符串视为标量(布尔)上下文中的false.

编辑

使用true(如“false”)作为false值的字符串表示法将如何更改现有代码的含义?我们可以说在这样的变化之后改变语义的代码不太可能是那么健壮/正确吗?我猜,在Perl中,字符串上下文是如此普遍,导致理智语义的唯一选项是如果布尔值在往返于字符串之后保留其值…

解决方法

各种逻辑运算符不返回空字符串,它们在所有三个简单标量类型中返回false或true值.它只是看起来像它返回一个空字符串,因为打印强制字符串上下文的参数:
#!/usr/bin/perl

use strict;
use warnings;

use Devel::Peek;

my $t = 5 > 4;
my $f = 5 < 4;

Dump $t;
Dump $f;

输出

SV = PVNV(0x100802c20) at 0x100827348
  REFCNT = 1
  FLAGS = (PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK)
  IV = 1
  NV = 1
  PV = 0x100201e60 "1"\0
  CUR = 1
  LEN = 16
SV = PVNV(0x100802c40) at 0x100827360
  REFCNT = 1
  FLAGS = (PADMY,pPOK)
  IV = 0
  NV = 0
  PV = 0x100208ca0 ""\0
  CUR = 0
  LEN = 16

对于那些不熟悉Perl 5内部的人来说,PVNV是一个标量结构,它包含三个简单的标量类型(整数IV,双精度浮点数NV和字符串PV).标志IOK,NOK和POK意味着整数,双精度和字符串值都是同步的(对于同步的一些定义),因此可以使用它们中的任何一个(即如果使用它,则不需要进行转换)作为整数,双精度或字符串).

我假设为字符串选择了空字符串,因为它较小,并且符合假字符串超过“0”的想法.忽略我的声明较小,“”和“1”的大小相同:十六个字符.它在转储中说得如此正确. Perl 5为字符串添加了额外的空间,以使其能够快速增长.

哦,我讨厌你.在研究这个问题时,我发现我在perlopquick年撒谎,现在必须找到解决这个问题的办法.如果只有你像所有的其他羊一样,只是接受Perl 5的表面奇怪的事实,我会做的更少的工作.

编辑部分的问题答案:

How would using string which is true (“false” for instance) as a string representation of false values change the meaning of existing code?

关于PL_sv_yes和PL_sv_no(比较运算符返回的规范的真值和值)的唯一特殊的事情是它们是只读的,并且由Perl创建,而不是正在运行的程序.如果您更改它们,则不会更改真实性测试,因此设置为“false”的PL_sv_no将被视为true.你甚至可以自己做这个(这个代码在Perl 5.18和最新的Perl之间的某个时间点停止工作)使用perl的未记录的功能

#!/usr/bin/perl

use strict;
use warnings;
use Scalar::Util qw/dualvar/;

BEGIN {
        # use the undocumented SvREADONLY function from Internals to
        # modify a reference to PL_sv_no's readonly flag
        # note the use of & to make the compiler not use SvREADONLY's
        # prototype,yet another reason prototypes are bad and shouldn't
        # be used
        &Internals::SvREADONLY(\!!0,0);

        # set PL_sv_no to a dualvar containing 0 and "false"
        ${\!!0} = dualvar 0,"false";
}

if (5 < 4) {
        print "oops\n";
}

输出

opps

这是因为真实性测试首先看到字符串.

Could we say that code that changes semantics after such a change is less robust/correct than it could have been?

它会直截了当.即使你限制自己将其设置为int 0或字符串“0”(两者均为false),它将中断一些有效的代码.

I guess string context is so pervasive in Perl that the only option leading to sane semantics is if boolean value preserve its value after round tripping to and from a string…

是.

猜你在找的Perl相关文章