perl - CHECK 和 INIT block 怎么了?

标签 perl include circular-dependency

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

简单地说 our $x_instance = new X 将给出 Can't locate object method "new" in the module that was not loaded first.

我想到了类似的东西

our $x_instance;
INIT { $x_instance = new X }

很有道理,所以我读了everything about the specially named blocks.

好吧,这在我做的一个简单测试中有效,但在我的实际应用程序中它系统地显示运行 INIT block 太晚了。 CHECK block 也会发生同样的情况。

我找到的唯一解释来自 Perl Monks恐怕我无法理解它。

是否有人解释了 Perl 如何执行 CHECKINIT block ,这超出了 perlmod 中的内容,并且会有所帮助我明白为什么我的 block 有时执行有时不执行吗?

顺便说一句,我只是想了解这一点——我并不是特别要求解决我最初的循环依赖问题,因为我有一个我相当满意的解决方法:

our $x_instance;
sub get_x_instance {
    $x_instance //= new X;
    return $x_instance;
}

最佳答案

INIT block 在运行时阶段开始之前立即按照编译器在编译阶段遇到它们的顺序执行。

如果您在运行时使用 require(或 do)来编译包含 INIT block 的 Perl 文件,那么该 block 将获胜'被执行。

很少有真正的理由使用 require 而不是 use

尽管您很自信,但必须有一个地方是您尝试在运行时加载包含 INIT block 的模块的地方。我建议你安装和使用 Carp::Always因此 Too late to run INIT block 消息伴随着堆栈回溯,这将帮助您找到错误的调用。

关于perl - CHECK 和 INIT block 怎么了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23733805/

相关文章:

linux - perl 脚本添加额外的大括号

perl - 是否可以检测当前的 while 循环迭代是否是 perl 中的最后一次?

perl - 如何改进我的 Twitter 流式爬虫?

php - WordPress 包含 SVG 文件错误

php - 从 include() 获取调用文件名

javascript - 循环依赖 Super 表达式必须为 null 或函数

python - 这种导入如何被视为循环(或者为什么我会收到 "ImportError: cannot import name EmailMessage"错误)

Perl 段落 n 元语法

c++ - C++ #includes 和类型变量的设计问题

f# - 使用循环引用设计和更好的选项对不可变类进行批判