我的Perl 5.26.2 x64(Cygwin)的经验行为是,当且仅当它的 string 部分为true时,doublevar才为true:
# 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'
自this起,自2009年以来就是这种情况。
问题:这种行为是否得到保证?
Boolean::String
说,这就是行为。但是,就向后兼容性而言,我不知道这是否值得依靠。
我也没有在perlsyn,Scalar::Util
或perldata#Context
中看到明确的陈述。
我在perldata#Scalar-values
中看到了以下内容:
如果未定义,则标量值在布尔意义上被解释为FALSE,如果为空字符串或数字0(或其等效字符串“ 0”),则为TRUE,否则为TRUE。布尔上下文只是一种特殊的标量上下文,在这种情况下,从未执行过对字符串或数字的转换。
不幸的是,“从未执行过转换……”的说法并没有告诉我解释器正在查看对偶变量的哪一部分!
类似地,Chas。欧文斯的related answer说
真实性测试首先查看字符串
但是,如果它查看字符串 first ,那么它查看 second 的时间是什么?
编辑我的理解是,如果overload
定义在变量是否为doublevar上,则bool
重载将得到控制。我想知道未超载的情况。
编辑2 池上的答案here指出,PL_sv_yes
和PL_sv_no
也有NV
({ {1}})组件。对于奖励积分:),如果对偶变量具有一个,则NV对真实性有影响吗? (让我知道该答案是否确实涉及到足以应得的一个单独问题。)
答案 0 :(得分:6)
是的,至少到目前为止。 SvTRUE_common
宏通常用于确定布尔上下文中SV
在何处为“ true”。这是在perl 5.26.1源中的sv.h
中定义的方式:
#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))
标量通过SvOK
测试(是否已定义)之后,下一个检查是SvPOK
-标量是否具有有效的内部字符串表示形式。 Dualvars总是通过此检查,因此对doublevar的布尔测试是其字符串表示形式是否为真(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 {
...
但是逻辑是相同的-先检查SvPOK
,然后返回字符串表示形式是否为空且不等于"0"
。
我认为未来的Perl开发人员会警惕更改这种长期存在的逻辑。
答案 1 :(得分:2)
这归结为如何在布尔上下文中以字符串或数字形式测试标量?
在Perl中,文档是最接近标准的文档。因此,如果文档中没有声明,则正式答案必须为:不,没有保证。
自从文档关闭了几次之后,谈论了上下文和转换,但具体来说不要阐明要完成的测试,我会说确实必须将其视为实施细节。您不能“依赖”它。
如果需要严格的可靠性,则一个解决方案是一个简单的类,可以确保测试您所需要的。
更实际地说,似乎是在if ($v)
中测试了字符串部分,如果没有,则进行数字测试(没有像文档所说的那样进行实际转换)。由于您询问的是已设置为dualvar的变量,因此对于这些变量,将始终只是字符串测试。