use feature qw/ say /;
use strict;
use warnings;
my $aref;
$#{$aref} = 4;
$aref->[2] = undef;
$aref->[3] = '';
foreach my $idx ( 0 .. $#{$aref} ) {
say "Testing $idx.";
say "\t$idx exists." if exists $aref->[$idx];
say "\t$idx defined." if defined $aref->[$idx];
}
OUTPUT:
Testing 0.
Testing 1.
Testing 2.
2 exists.
Testing 3.
3 exists.
3 defined.
Testing 4.
Мы предварительно выделили пять мест в анонимном массиве @{$aref}
.Верхний индекс - 4
.Мы можем найти верхний индекс так же, как мы его создали;путем проверки значения $#{$aref}
.Мы можем проверить на существование.Мы знаем, что все между 0
и 4
было создано.Но Perl сообщает, что «существует» только для элементов массива, которым определенно было что-то назначено (даже если это undef
).Следовательно, $aref->[2]
, как сообщается, существует, но не определен.Ради интереса, мы присвоили ''
$aref->[3]
, чтобы увидеть отчет об испытаниях, определенный один раз.Но короткая история заключается в том, что, хотя массив предварительно расширен, мы все равно можем проверить разницу между элементом, инициализируемым с помощью undef
, и элементом, являющимся undef
посредством предварительного расширения массива, используя 'exists
'.
Не могу сказать, что это задокументированное поведение exists
.Так что нет никаких гарантий, что когда-нибудь это не изменится.Но он работает на 5.8, 5.10, 5.12 и 5.14.
Итак, ищем простой способ найти, какие элементы были инициализированы, какие определены, а какие нет, вот пример:
use feature qw/ say /;
use strict;
use warnings;
my $aref;
$#{$aref} = 4;
$aref->[2] = undef;
$aref->[3] = '';
my @initialized = grep { exists $aref->[$_] } 0 .. $#{$aref};
my @defined = grep { defined $aref->[$_] } 0 .. $#{$aref};
my @uninitialized = grep { not exists $aref->[$_] } 0 .. $#{$aref};
my @init_undef = grep { exists $aref->[$_] and not defined $aref->[$_] } 0 .. $#{$aref};
say "Top index is $#{$aref}.";
say "These elements are initialized: @initialized.";
say "These elements are not initialized: @uninitialized.";
say "These elements were initialized with 'undef': @init_undef.";
say "These elements are defined: @defined."