gpt4 book ai didi

perl - 为什么先销毁包含的对象?

转载 作者:行者123 更新时间:2023-12-04 22:43:13 25 4
gpt4 key购买 nike

在下面的代码片段中,类 Foo 的对象包含对类 Bar 的对象的引用.我希望 Foo对象在 Bar 之前被销毁目的。不幸的是,这并不总是发生。奇怪的是,我在不同的系统上得到了不同的行为:在我的笔记本电脑和台式机上,代码总是正确运行,而在我尝试过的 2 个 VPS 上,析构函数以相反的顺序运行(大部分时间)。所有四个系统都运行相同版本的 perl(x86_64 linux 上的 5.20.2)。

此外,这仅在子项(以下称为 abcd)包含对 Foo 的引用时发生。目的。如果我删除它,问题就会消失。

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

my $foo = Foo->new;

sub abcd {
$foo;
}

####################

package Foo;

sub new {
bless {bar => Bar->new}, 'Foo';
}

sub DESTROY {
my ($self) = @_;
defined $self->{bar} or print "bar is undefined, this should not happen\n";
}

####################

package Bar;

sub new {
bless {}, 'Bar';
}

最佳答案

当涉及到程序退出时发生的全局破坏时, perlobj 清楚了

The order in which objects are destroyed during the global destruction before the program exits is unpredictable.



如果没有 sub abcd,情况很明显。在您发布的测试程序中。对于 sub,对对象的最后一个引用在 sub 内部,因此它也达到了全局销毁。 (我在这两种情况下也有不同的行为,但鉴于上述引用,这是毫无意义的。)

因此,在这两种情况下,无论有没有 sub,对象都以不可预测的顺序被销毁。

当一个对象因为最后一个引用超出范围而被销毁时,情况就不同了。要查看此类行为,我们可以添加 undef $foo;作为最后一行,触发受控破坏
my $foo = Foo->new;

undef $foo;

END { say "END block." }

sub abcd { $foo; }

这导致 Foo首先被摧毁,无论有没有潜艇。它也发生在 END 之前阻止并在全局销毁阶段之前。 (在 DESTROYFoo 中添加打印到 Bar 以查看。)

关于perl - 为什么先销毁包含的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38938369/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com