Почему канонические "истинные" и "ложные" значения 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
Другие вопросы по тегам