CHECK和INIT块怎么了?

sco*_*ozy 3 perl circular-dependency include

我对Perl模块有一个循环依赖问题:说包X使用Y并想持有对Y实例的静态引用,而包Y使用X并想持有对X实例的静态引用。

简而言之,在未首先加载的模块中our $x_instance = new X将为“无法找到对象方法”提供“新”

我想像

our $x_instance;
INIT { $x_instance = new X }
Run Code Online (Sandbox Code Playgroud)

很有道理,所以我阅读了有关特殊命名块的所有内容。

好吧,这在我做的简单测试中有效,但在我的实际应用中,它系统地显示了运行INIT块为时已晚。情况与此相同CHECK的块。

我发现的唯一解释是来自Perl Monks,恐怕我对此没有多大意义。

有人对Perl如何执行CHECKINIT超出其内容的块有一个解释perlmod,并且可以帮助我理解为什么我的块有时执行而有时不执行的原因吗?

顺便说一句,我只想了解这一点,因为我有一个合理的解决方法,我并不是很想解决我原来的循环依赖问题:

our $x_instance;
sub get_x_instance {
    $x_instance //= new X;
    return $x_instance;
}
Run Code Online (Sandbox Code Playgroud)

Bor*_*din 5

INIT 块是在运行时阶段开始之前立即执行的,其顺序是编译器在编译阶段遇到它们的顺序。

如果您在运行时使用use require(或do)来编译包含一个INIT块的Perl文件,则该块将不会执行。

很少有真正的理由require优先使用use

尽管有信心,但必须在某个地方尝试在运行时装载包含INIT块的模块。我建议您进行安装和使用,Carp::Always以便Too late to run INIT block消息附带堆栈回溯,以帮助您找到错误的调用。