Почему канонические "истинные" и "ложные" значения Perl являются внутренними?
Perl имеет каноническое значение "истина" и "ложь", которые он использует для случаев логического отрицания с !
или же not
,
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
print Dumper !1; # outputs $VAR1 = '';
print Dumper !!1; # outputs $VAR1 = 1;
Пока все хорошо.
Но когда я смотрю на значения с Devel::Peek
Понятно, что они не эквивалентны буквальному ''
а также 1
, они оба значения SV PVNV.
$ perl -MDevel::Peek -E 'Dump ""; Dump !1;' 2>&1 | grep '^SV'
SV = PV(0x15e5140) at 0x1603298
SV = PVNV(0x15e3010) at 0x7814b0
$ perl -MDevel::Peek -E 'Dump 1; Dump !!1;' 2>&1 | grep '^SV'
SV = IV(0xfce228) at 0xfce238
SV = PVNV(0xfae030) at 0x7819f0
Я проверил это с Perl 5.16.3 и Perl 5.20.0.
Разве PVNV не намного больше, чем простой IV? Это случай, когда Perl торгует памятью на скорость?
2 ответа
Не просто логическое отрицание; эти значения возвращаются многими встроенными
На самом деле нет проблемы с памятью, поскольку существует только один экземпляр каждого из них.
В частности, ложное значение должно быть PVNV, так как его строковое значение ''
и его числовое значение 0
не выводятся друг от друга (по крайней мере, не вызывая предупреждение).
Я полагаю, что ответ здесь заключается в том, что да, PVNV больше, но Perl хранит в памяти только одну копию истинного значения и одну копию ложного значения, так что это не значит, что вам не хватит памяти с большим количеством Булевы значения в вашем скрипте.
Я получаю это из подсчета ссылок (REFCNT
) из этого Devel::Peek
выход:
$ perl -MDevel::Peek -E 'Dump !1; Dump !!1;' 2>&1 | grep REFCNT
REFCNT = 2147483646
REFCNT = 2147483644