我有一个Perl脚本生成一个对象的弱引用数组。一旦这些对象中的一个超出范围,数组中对它的引用将变为未定义。
ex(伪代码):
# Imagine an array of weak references to objects
my @array = ( $obj1_ref, $obj2_ref, $obj3_ref );
# Some other code here causes the last strong reference
# of $obj2_ref to go out of scope.
# We now have the following array
@array = ( $obj1_ref, undef, $obj3_ref )
有没有办法让未定义的引用在数组未定义后自动从数组中删除?
我想要@array = ($obj1_red, $obj3_ref )
。
我尝试了这个解决方案但它没有工作:
#!/usr/bin/perl
use strict;
use warnings;
{
package Object;
sub new { my $class = shift; bless({ @_ }, $class) }
}
{
use Scalar::Util qw(weaken);
use Data::Dumper;
my $object = Object->new();
my $array;
$array = sub { \@_ }->( grep defined, @$array );
{
my $object = Object->new();
@$array = ('test1', $object, 'test3');
weaken($array->[1]);
print Dumper($array);
}
print Dumper($array);
输出:
$VAR1 = [
'test1',
bless( {}, 'Object' ),
'test3'
];
$VAR1 = [
'test1',
undef,
'test3'
];
未自动从数组中删除undef。
我错过了什么吗?
我还尝试在对象的DESTROY方法中从数组中删除未定义的值,但这似乎也不起作用。看起来,由于物体在技术上仍然没有被销毁,并且#34;然而,在DESTROY方法完成之前,仍然会定义弱引用...
答案 0 :(得分:1)
不,没有使用神奇的(例如绑定的)阵列。
如果你有一个数组而不是一个数组的引用,你可以使用以下方法有效地过滤掉未定义的元素,而不需要#34;强化"任何参考文献。
$array = sub { \@_ }->( grep defined, @$array );
事实上,根本不会复制这些值。只有" C指针"复制。
答案 1 :(得分:0)
Perl不会自动为你做这件事。你有几个选择。首先是每次使用时自行清洁:
my @clean = grep { defined $_ } @dirty;
或者您可以创建tie'd array并将该功能添加到FETCH*
和POP
挂钩。