标志“pIOK”是什么意思?

What does flag `pIOK` mean?

当使用 Devel::Peek 转储 perl SV 时,我可以看到:

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

但是找不到描述pIOK的意思。

我试着在 Devel::Peek, perlapi, perlguts, perlxs ... 在消息来源中,我发现:

{SVp_IOK, "pIOK,"}

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

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

This flag indicates that the object has a valid non-public IVX field value. It can only be set for value type SvIV or subtypes of it.

更新

Why private and public flags are differ

pIOK就是Devel::Peek表示位掩码SVp_IOK对应的位的方式。 p 表示一个 "private" 标志,它与 "public" 标志 IOK (位掩码 SVf_IOK

形成一对

私有标志的确切含义在 perl 版本中发生了变化,但一般而言,它们表示 IV(或 NVPV)字段 SV 在某种程度上是 "inaccurate"

最常见的 pIOK 单独设置的情况(如果设置 IOK,则始终设置 pIOK)是 PV 已转换为一个数字 NV 值。 NVIV 字段都已填充,但如果 IV 值不是数字的准确表示(即已被截断),则设置 pIOKIOK 已清除

此代码显示了达到该状态的方法。变量 $pi_str 被设置为 π 的 字符串 值,并通过添加 0.0 并将其存储到 $pi_num 中转换为浮点值。 Devel::Peek 现在显示 NOK/pNOKPOK/pPOKset,但只有 pIOKIOK 保持清晰。查看 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"[=11=]
  CUR = 7
  LEN = 10
  COW_REFCNT = 1

Perl v5.16 及之前习惯使用标志来指示 "magic" 变量(例如 tied 值)因为 IV 中的值字段不能直接使用。这在 v5.18 及更高版本中发生了变化,魔法值现在使用 pIOK 的方式与任何其他值相同