自删除数组元素(一旦它们变得未定义)

时间:2015-08-19 16:42:56

标签: arrays perl oop weak-references

我有一个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。

我错过了什么吗?

编辑2:

  

我还尝试在对象的DESTROY方法中从数组中删除未定义的值,但这似乎也不起作用。看起来,由于物体在技术上仍然没有被销毁,并且#34;然而,在DESTROY方法完成之前,仍然会定义弱引用...

2 个答案:

答案 0 :(得分:1)

不,没有使用神奇的(例如绑定的)阵列。

如果你有一个数组而不是一个数组的引用,你可以使用以下方法有效地过滤掉未定义的元素,而不需要#34;强化"任何参考文献。

$array = sub { \@_ }->( grep defined, @$array );

事实上,根本不会复制这些值。只有" C指针"复制。

答案 1 :(得分:0)

Perl不会自动为你做这件事。你有几个选择。首先是每次使用时自行清洁:

my @clean = grep { defined $_ } @dirty;

或者您可以创建tie'd array并将该功能添加到FETCH*POP挂钩。