gpt4 book ai didi

perl - 为什么 Perl 使用空字符串来表示 boolean false 值?

转载 作者:行者123 更新时间:2023-12-03 13:19:05 25 4
gpt4 key购买 nike

在标量( boolean )上下文中计算表达式时,Perl 使用显式值 1如果表达式的计算结果为 true,则作为结果;如果表达式的计算结果为 false,则返回空字符串。
我很好奇为什么 Perl 使用空字符串来表示 boolean 假值而不是 0这似乎更直观。

请注意,我不关心 Perl 在标量( boolean )上下文中将空字符串视为 false。

编辑

使用为真的字符串(例如 "false")作为假值的字符串表示会如何改变现有代码的含义?我们是否可以说在这种更改之后更改语义的代码不如原本的稳健/正确?我猜字符串上下文在 Perl 中如此普遍,导致语义健全的唯一选择是 boolean 值是否在往返于字符串之间保持其值......

最佳答案

各种逻辑运算符不返回空字符串,它们在所有三种简单的标量类型中都返回 false 或 true 值。看起来它返回一个空字符串,因为 print在其参数上强制使用字符串上下文:

#!/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,IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x100208ca0 ""\0
CUR = 0
LEN = 16

对于那些不熟悉 Perl 5 内部结构的人, PVNV是一个标量结构,包含所有三种简单的标量类型(整数 IV、 double 浮点数 NV 和字符串 PV)。旗帜 IOK , NOK , 和 POK意味着整数、 double 和字符串值都是同步的(对于同步的某些定义),因此可以使用它们中的任何一个(即,如果将其用作整数、 double 或字符串,则无需进行转换)。

我假设为假字符串选择了空字符串,因为它比 "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将被视为真实。您甚至可以使用 perl 的未记录特性自己执行此操作(此代码在 Perl 5.18 和最新 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”(两者都是错误的),它也会破坏一些有效的代码。

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 - 为什么 Perl 使用空字符串来表示 boolean false 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3914129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com