5

当倾倒 perl SV 时,Devel::Peek我可以看到:

SV = IV(0x1c13168) at 0x1c13178
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 2

但找不到描述是什么pIOK意思。

我试着看它,,,,Devel::Peek......在我发现的来源perlapiperlgutsperlxs

{SVp_IOK, "pIOK,"}

但还是找不到是什么SVp_IOK。它是什么?

UPD
我找到了这个文件。它阐明了标志的含义以及它们的位置。(注意这个 DOC 有点过时了)

在此处输入图像描述

此标志指示对象具有有效的非公共 IVX 字段值。它只能为值类型 SvIV 或其子类型设置。

UPD

为什么私有和公共标志不同

4

1 回答 1

7

pIOK是如何Devel::Peek表示与位掩码对应的位SVp_IOK。表示“p私有”标志,它与“公共”标志IOK(位掩码SVf_IOK)形成一对

私有标志的确切含义在 perl 版本中有所不同,但一般来说,它们意味着 的IV(或NVPV)字段SV在某些方面是“不准确的”

pIOK单独设置的最常见情况(如果设置,pIOK则始终IOK设置)是 aPV已转换为数值NV。和字段均已填充,但如果该NV值不是数字的准确表示(即已被截断),则设置但被清除IVIVpIOKIOK

此代码显示了达到该状态的方法。变量$pi_str设置为 π 的字符串值,并通过添加 0.0 将其转换为浮点值并将其存储到$pi_num. Devel::Peek现在显示NOK/pNOKand POK/pPOKare set,但只有pIOKwhileIOK仍然清晰。查看该IV值我们可以看出原因:它设置为 3,这是缓存的值,int $pi_str以防我们再次需要它,但它不是"3.14159"整数形式的字符串的准确表示

use strict;
use warnings 'all';

use Devel::Peek 'Dump';

my $pi_str = "3.14159";

my $pi_num = $pi_str + 0.0;

Dump $pi_str;

输出

SV = PVNV(0x28fba68) at 0x3f30d30
  REFCNT = 1
  FLAGS = (NOK,POK,IsCOW,pIOK,pNOK,pPOK)
  IV = 3
  NV = 3.14159
  PV = 0x3fb7ab8 "3.14159"\0
  CUR = 7
  LEN = 10
  COW_REFCNT = 1

Perl v5.16 及之前使用标志来指示“魔术”变量(例如绑定值),因为IV字段中的值不能直接使用。这在 v5.18 及更高版本中进行了更改,现在魔法值pIOK的使用方式与任何其他值相同

于 2018-01-16T12:25:40.980 回答