我可以在其中创建一个带有“空插槽”的数组:
$ perl -wde 1
...
DB<1> $x[2] = 0
DB<2> x \@x
0 ARRAY(0x103d5768)
0 empty slot
1 empty slot
2 0
或
DB<3> $#y = 4
DB<4> x \@y
0 ARRAY(0x103d5718)
0 empty slot
1 empty slot
2 empty slot
3 empty slot
4 empty slot
请注意:这与分配undef
不同。
但是如何使用[
和]
为匿名数组指定?
这不起作用:
DB<5> x [,,0]
syntax error at (eval 27)[/usr/local/lib/perl5/5.10.0/perl5db.pl:638] line 2, near "[,"
这也失败了,因为我只得到指定的值:
DB<6> x []->[2] = 0
0 0
奖金问题:如何在Perl脚本中检查“空数组插槽”?
背景:在我的测试脚本中,我希望能够精确地比较数组内容。例如,我想区分“未分配”和“使用undef值分配”。
感谢您的任何见解。
答案 0 :(得分:5)
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."
答案 1 :(得分:3)
应该这样做:
$a=[];
$#$a=4;
答案 2 :(得分:1)
背景:在我的测试脚本中,我希望能够精确地比较数组内容。例如,我想区分“未分配”和“使用undef值分配”。
您可以检查索引是否超过了结尾。除此之外,你无能为力。
$x = [];
undef $x->[9999];
print scalar @$x;
打印10000. undef $x->[9999]
等同于$x->[9999] = undef;
因为没有元素0到9998,perl会将所有插入元素神奇地分配给undef
。
答案 3 :(得分:-1)
您只能通过XS代码执行此类操作(请参阅示例Devel::Peek
)。 *::Util
包中暴露了一些但不是全部。 (我一直在研究调试/跟踪包,所以我对此了解得比任何人都需要的更多......)