【问题标题】:What's up with CHECK and INIT blocks?CHECK 和 INIT 块是怎么回事?
【发布时间】:2014-07-07 04:20:13
【问题描述】:

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

简单地说our $x_instance = new X 会在没有先加载的模块中给出Can't locate object method "new"

我想到了类似的东西

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

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

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

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

是否有人解释了 Perl 如何执行超出 perlmod 的块的 CHECKINIT 块,并能帮助我理解为什么我的块有时被执行,有时不被执行?

顺便说一句,我只是想理解这一点——我并不是专门要求解决我原来的循环依赖问题,因为我有一个我相当满意的解决方法:

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

【问题讨论】:

  • 要回答您的问题,缺少一个重要的关键信息:由于您的方法适用于 INIT,我们需要有关您的“实际应用程序”及其环境的信息...您是 evalutating 您的部分吗?代码?
  • 你使用的是什么版本的 Perl?
  • @deviolog,我不使用eval,但我使用do。为require 更改所有do 并没有改变。不过,我加载了许多 CPAN 模块。 perlINIT 的使用方式与 eval 的使用之间是否存在关系?
  • @scozy ... ^_^ 你告诉我们你读过“everything about the specially named blocks”。请再次查看该文档:)
  • @deviolog,你到底想让我看什么?如果是关于 INITinside 代码的段落由 require 等人编译,则无关紧要,我的 INIT 块在使用 use 导入的包中。

标签: perl include circular-dependency


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-10-09
    相关资源
    最近更新 更多