我有以下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
阵列中移除(听起来很残酷),而其他两个孩子仍然存在。
但是在运行此代码时,我得到以下输出:
出现以下错误消息:
在全局销毁期间在第28行的数字eq(==)中使用未初始化的值。
(在清理中)不能调用方法"孩子"在全局销毁期间第25行的未定义值。
现在澄清这个错误。 。
第25行是这一行:for my $index (0 .. $#{$self->parent->children()}) {
无法拨打$self->parent()
! (可以通过尝试打印$self->parent()
)
该错误似乎表明在父项已被销毁后子项被销毁,因此父项现在未定义。 但被销毁的子对象包含对父级的 STRONG 引用,因此在子级被销毁之前不应允许销毁父对象。
这怎么可能?