Perl中CHECK,UNITCHECK和INIT块的用处是什么?

时间:2009-11-04 03:33:08

标签: perl compilation

我知道他们都做了什么,但从未发现自己处于需要其中任何一个的境地。我曾多次使用BEGIN块,偶尔使用END块。当您需要在代码运行之前调整环境时,BEGIN特别有用,并且我在某些调试情况下使用END来捕获重要的状态信息,以便难以跟踪致命错误。

您曾使用过CHECKUNITCHECK还是INIT?如果是这样,那该怎么办? BEGIN块是否会由于某种原因而无法满足?

块的文档位于PerlDoc

4 个答案:

答案 0 :(得分:7)

CHECK块的一个有趣用法是Simon Cozens(O'Reilly)在第1章的“高级Perl编程”中的“稍后用CHECK做事”部分。他展示了如何实现“最终”类似java的属性

此外,Devel :: Sub :: Trace使用INIT块来嵌入跟踪(此信息来自POD for Devel :: Hook,这是用于处理这些命名块的模块)

答案 1 :(得分:5)

我有一个包import函数,它可以执行一些繁重的处理,然后进行eval调用。你如何调试这样的东西?导入函数在use模块运行时运行,该模块在编译时发生(就像在BEGIN块中一样)。出于某种原因(我认为这是因为我需要使用heredoc表示法将参数传递给import,但它可能是其他的东西),说require Module; Module->import(@args)还不够好。

所以我的解决方法是在eval中为import构建字符串,并将其保存为另一个变量。 然后我在eval块中运行了INIT。运行调试器时,第一个执行点位于INIT块的开头,我可以使用调试器逐步执行eval语句。

答案 2 :(得分:3)

如您所知,在编译时运行BEGIN块。所以我将它保存到需要运行的代码中,以便导入我的模块。

我编写了一个脚本包装器,用于完成在几百个脚本中发生的样板代码中所做的所有操作。

  • 我需要做的事情才能使模块读数为use - d。我在BEGIN块和import子块中运行了。
  • 但是,还有初始化脚本将使用的服务的样板。因此,我在INIT块中运行了这些操作。
  • 并在END块中运行必要的清理并退出代码。

我认为如果用XS引擎编写模块,CHECK是有意义的,但我只使用了几次。有一次我认为是检查 Intermediate Perl 中的建议。我不能随便记住其他原因。

但是当我觉得代码是脚本的一部分时,我会使用INIT块,而不是设置模块。从本质上讲,我只在编译期间做必要的事情。

答案 3 :(得分:1)

perlmod 解释了这些特殊功能块,但实际上只使用BEGINEND。 它们只是CV,LIFO或FIFO的数组。 这些块允许在运行代码时单独计时,与源文件中的位置无关。因此,您可以将代码段保持在一起,但它们会在不同的时间执行(PHASES)。

最初添加了

CHECK ,以便在模块初始化(使用包)之后以及在主模块之前以固定顺序运行编译器套件 O -MO=C...)程序,能够在那里存储执行上下文。这将从运行时(之后)分离编译时(之前)。 CHECK后perl -c停止。

由于我是编译器的维护者,因此我广泛使用CHECK和-MO =。我的模块compile()方法在CHECK块中由 O 调用。使用 Od 调试O ),我调用compile方法不在CHECK中,但稍后在INIT中,所以调试器会进入它。默认情况下,调试器不会进入CHECK块,您必须强制使用$DB::single=1或使用 Od

UNITCHECK 后来被添加到细粒度模块编译和加载,尤其是。 .pmc个文件。

到目前为止,我从未使用过它。它也可以在运行时发生,因此我可以将它用于运行时加载模块的类型检查。

然后添加

INIT 以允许单独的类初始化。

我很少使用它,但它很方便。