我对Perl模块存在循环依赖问题:假设包X
使用Y
并希望保留对Y
实例的静态引用,并且包Y
使用X
并希望保留对X
实例的静态引用。
简单地说our $x_instance = new X
会给找不到首先没有加载的模块中的对象方法“new”。
我想像
our $x_instance;
INIT { $x_instance = new X }
会有意义,所以我读了everything about the specially named blocks.
嗯,这可以在我做的一个简单的测试中工作,但在我的实际应用程序中它系统地显示运行INIT块太迟了。 CHECK
块也是如此。
我发现的唯一解释是来自Perl Monks,我担心我无法理解它。
有人对Perl如何执行CHECK
和INIT
阻止超出perlmod
范围的内容有所解释,并且会帮助我理解为什么我的阻止并且有时执行和有时候不是吗?
顺便说一句,我只是想了解这一点 - 我并没有特别要求解决我原来的循环依赖问题,因为我有一个合理的解决方法:
our $x_instance;
sub get_x_instance {
$x_instance //= new X;
return $x_instance;
}
答案 0 :(得分:4)
INIT
块在运行时阶段之前立即按照编译器在编译阶段遇到它们的顺序执行。
如果在运行时使用require
(或do
)来编译包含INIT
块的Perl文件,则该块将不会被执行。
很少有真正的理由使用require
优先于use
。
尽管您有信心,但必须才能在运行时加载包含INIT
块的模块。我建议您安装并使用Carp::Always
,以便Too late to run INIT block
消息附带堆栈回溯,以帮助您找到错误的呼叫。