在引用超出范围之前,对具有强引用的对象进行了销毁?

时间:2015-08-19 20:08:20

标签: perl oop destructor weak-references

我有以下Perl代码:

#!/usr/bin/perl
use strict;
use warnings;

# Parent object
package Parent;
{
    use Moose;

    has 'children' => (is => 'rw', isa => 'ArrayRef[Child]', default => sub { [] });
}

# Child object
package Child;
{
    use Moose;

    has 'parent' => (is => 'ro', isa => 'Parent', required => 1);

    # Child DEMOLISHER!!!! >:)
    sub DEMOLISH {
        my ($self) = @_;

        # Loop through the known children of the parent
        for my $index (0 .. $#{$self->parent->children()}) {

            # Remove the destroyed child
            if ($self->parent->children->[$index] == $self) {
                splice @{$self->parent->children()}, $index, 1;
                return;
            }
        }
    }
}

package Test;
{
    use Scalar::Util qw(weaken);
    use Data::Dumper;

    # Create a parent object
    my $parent = Parent->new();
    {

        # Create children (with STRONG refs to the parent)
        my $child  = Child->new('parent' => $parent);
        my $child2 = Child->new('parent' => $parent);
        my $child3 = Child->new('parent' => $parent);

        # Add children to the parents list of children
        push @{$parent->children()}, ($child, $child2, $child3);

        # Weaken the last childref
        weaken($parent->children->[-1]);

        # Print the children
        print Dumper($parent->children());
    }

    # The weakened child is out of scope and should be removed
    print Dumper($parent->children());
}

此代码创建一个父对象,然后创建3个子对象(每个子对象都具有对父对象的强引用)。然后一个孩子被削弱了。当孩子们超出范围时,预计被削弱的孩子将被摧毁并从父母的children阵列中移除(听起来很残酷),而其他两个孩子仍然存在。

但是在运行此代码时,我得到以下输出:

enter image description here

出现以下错误消息:

  

在全局销毁期间在第28行的数字eq(==)中使用未初始化的值。

     

(在清理中)不能调用方法"孩子"在全局销毁期间第25行的未定义值。

现在澄清这个错误。 。

第25行是这一行:for my $index (0 .. $#{$self->parent->children()}) {

无法拨打$self->parent()! (可以通过尝试打印$self->parent()

的值来测试

该错误似乎表明在父项已被销毁后子项被销毁,因此父项现在未定义。 被销毁的子对象包含对父级的 STRONG 引用,因此在子级被销毁之前不应允许销毁父对象。

这怎么可能?

0 个答案:

没有答案