cxw*_*cxw 9 perl boolean-expression language-lawyer truthiness
我的Perl 5.26.2 x64(Cygwin)的经验行为是,当且仅当其字符串部分是真实时,双变量才是真实的:
# Falsy number, truthy string => truthy
$ perl -MScalar::Util=dualvar -E 'my $v=dualvar 0, "foo"; say "yes" if $v'
yes
# Truthy number, falsy string => falsy
$ perl -MScalar::Util=dualvar -E 'my $v=dualvar 1, ""; say "yes" if $v'
# Truthy number, truthy string => truthy
$ perl -MScalar::Util=dualvar -E 'my $v=dualvar 1, "foo"; say "yes" if $v'
yes
# Falsy number, falsy string => falsy
$ perl -MScalar::Util=dualvar -E 'my $v=dualvar 0, ""; say "yes" if $v'
Run Code Online (Sandbox Code Playgroud)
自2009年以来一直如此.
问题:这是保证的行为吗?
Boolean::String说这是行为.但是,就向后兼容性而言,我不知道这是否可以依赖.我还没有看到在明确声明perlsyn,Scalar::Util或perldata#Context.
我确实看到以下内容perldata#Scalar-values:
如果未定义标量值,则在布尔义上将标量值解释为FALSE,空字符串或数字0(或其等效字符串,"0"),如果是其他任何值,则为TRUE.布尔上下文只是一种特殊的标量上下文,不会执行到字符串或数字的转换.
不幸的是,"没有进行转换......"的说法并没有告诉我解释器正在考虑的双变量的哪个部分!
同样,Chas.欧文斯的相关答案说明了这一点
真实性测试首先考虑字符串
但是,如果它首先查看字符串,它看起来第二,什么时候?
编辑我的理解是,如果overload在变量doublevar上定义,则bool过载将控制.我想知道非重载的情况.
编辑2 ikegami的答案在这里指出,PL_sv_yes并且PL_sv_no 还有一个NV(double)组件.对于奖励积分:),如果双变量有一个,NV对真实性有任何影响吗?(请告诉我,如果答案实际上足够值得一个单独的问题.)
是的,至少到目前为止.该SvTRUE_common宏通常用来决定在哪里的SV是在布尔环境"真".以下是sv.hperl 5.26.1源代码的定义方式:
#define SvTRUE_common(sv,fallback) ( \
!SvOK(sv) \
? 0 \
: SvPOK(sv) \
? SvPVXtrue(sv) \
: (SvFLAGS(sv) & (SVf_IOK|SVf_NOK)) \
? ( (SvIOK(sv) && SvIVX(sv) != 0) \
|| (SvNOK(sv) && SvNVX(sv) != 0.0)) \
: (fallback))
Run Code Online (Sandbox Code Playgroud)
标量通过SvOK测试后(无论是否已定义),下SvPOK一项检查是- 标量是否具有有效的内部字符串表示.Dualvars总是通过这个检查,因此dualvar的布尔测试是它的字符串表示是否为true(SvPVXtrue(...)).
perl 5.6.2中的代码不同
I32
Perl_sv_true(pTHX_ register SV *sv)
{
if (!sv)
return 0;
if (SvPOK(sv)) {
register XPV* tXpv;
if ((tXpv = (XPV*)SvANY(sv)) &&
(tXpv->xpv_cur > 1 ||
(tXpv->xpv_cur && *tXpv->xpv_pv != '0')))
return 1;
else
return 0;
}
else {
...
Run Code Online (Sandbox Code Playgroud)
但逻辑是相同的 - 先检查SvPOK然后返回字符串表示是否为空且不等于"0".
我认为未来的Perl开发人员会对改变这种长期存在的逻辑保持警惕.
| 归档时间: |
|
| 查看次数: |
147 次 |
| 最近记录: |