各种逻辑运算符不返回空字符串,它们在所有三个简单标量类型中返回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…
是.