Что означает флаг `pIOK`?
При сбросе Perl SV с Devel::Peek
Я могу видеть:
SV = IV(0x1c13168) at 0x1c13178
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 2
Но не могу найти описание, что pIOK
имею в виду.
Я пытался посмотреть на это Devel::Peek
, perlapi
, perlguts
, perlxs
... В источниках я обнаружил, что:
{SVp_IOK, "pIOK,"}
Но до сих пор не могу найти то, что SVp_IOK
является. Что это?
UPD
Я нашел этот документ. Это пролило свет на то, что означают флаги и где они расположены. (остерегайтесь этого DOC немного устарел)
Этот флаг указывает, что объект имеет допустимое непубличное значение поля IVX. Его можно установить только для типа значения SvIV или его подтипов.
UPD
1 ответ
pIOK
я показываю Devel::Peek
представляет бит, соответствующий битовой маске SVp_IOK
, p
указывает на "частный" флаг, и он формирует пару с "публичным" флагом IOK
(битовая маска SVf_IOK
)
Точное значение приватных флагов изменилось в разных версиях Perl, но в общих чертах они означают, что IV
(или же NV
или же PV
) поле SV
является "неточным" в некотором роде
Наиболее распространенная ситуация, когда pIOK
устанавливается самостоятельно (pIOK
всегда устанавливается, если IOK
установлен) где PV
был преобразован в числовой NV
значение. NV
а также IV
оба поля заполнены, но если IV
значение не является точным представлением числа (то есть оно было усечено), то pIOK
установлен, но IOK
очищается
Этот код показывает способ достижения этого состояния. переменная $pi_str
устанавливается в строковое значение для π и преобразуется в значение с плавающей запятой путем добавления 0.0 и сохранения его в $pi_num
, Devel::Peek
теперь показывает, что NOK/pNOK
а также POK/pPOK
установлены, но только pIOK
в то время как IOK
остается ясным. Глядя на 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
так же, как и любое другое значение