问题 为什么Perl以LIFO顺序运行END和CHECK块?


我没有深刻或有趣的问题 - 我只是好奇为什么会如此。


5681
2017-08-24 10:41


起源



答案:


假设每个包都依赖于之前的一切正确功能。 END块旨在“清理和关闭”程序包完成之前可能需要处理的任何内容。但是这项工作可能依赖于之前启动的软件包的正确运行,如果允许它们运行其END块,则可能不再适用。

如果你以任何其他方式做到这一点,可能会有不好的错误。


7
2017-08-24 10:44





这是一个可能有用的简单示例:

# perl
BEGIN { print "(" }
END   { print ")" }

BEGIN { print "[" }
END   { print "]" }

这输出: ([])

如果 END 然后是一个FIFO BEGIN/END 不会很好地在一起工作。

更新  - 摘录自 编程Perl 第3版,第18章:编译 - 前卫编译器,复古口译员,第483页:

如果文件中有多个END块,它们的执行顺序与它们的定义相反。也就是说,定义的最后一个END块是程序完成时执行的第一个块。如果您将它们配对,这种反转可以使相关的BEGIN和END块以您期望的方式嵌套

/ I3az /


6
2017-08-24 11:53



这种问题引发了一个问题。您创建了一种情况,其中BEGIN和END块必须以您想要解释它们为什么要按您想要的顺序触发的顺序触发。但是,没有任何先验的理由,你必须有,甚至应该两者一起工作。 - brian d foy
@brian d foy =>这显然是一个简单的例子,但想象一下这些BEGIN / END对中的每一个都在不同的模块中,而模块2在它的结束块中依赖于模块1。如果它是FIFO,模块1将在模块2完成使用之前自行清理。您当然可以使用BEGIN和END,但一般用法是BEGIN为后续代码设置执行环境,END处理执行后清理。这两者显然具有逻辑关系,即使不必在所有模块中使用该关系。 - Eric Strom


答案:


假设每个包都依赖于之前的一切正确功能。 END块旨在“清理和关闭”程序包完成之前可能需要处理的任何内容。但是这项工作可能依赖于之前启动的软件包的正确运行,如果允许它们运行其END块,则可能不再适用。

如果你以任何其他方式做到这一点,可能会有不好的错误。


7
2017-08-24 10:44





这是一个可能有用的简单示例:

# perl
BEGIN { print "(" }
END   { print ")" }

BEGIN { print "[" }
END   { print "]" }

这输出: ([])

如果 END 然后是一个FIFO BEGIN/END 不会很好地在一起工作。

更新  - 摘录自 编程Perl 第3版,第18章:编译 - 前卫编译器,复古口译员,第483页:

如果文件中有多个END块,它们的执行顺序与它们的定义相反。也就是说,定义的最后一个END块是程序完成时执行的第一个块。如果您将它们配对,这种反转可以使相关的BEGIN和END块以您期望的方式嵌套

/ I3az /


6
2017-08-24 11:53



这种问题引发了一个问题。您创建了一种情况,其中BEGIN和END块必须以您想要解释它们为什么要按您想要的顺序触发的顺序触发。但是,没有任何先验的理由,你必须有,甚至应该两者一起工作。 - brian d foy
@brian d foy =>这显然是一个简单的例子,但想象一下这些BEGIN / END对中的每一个都在不同的模块中,而模块2在它的结束块中依赖于模块1。如果它是FIFO,模块1将在模块2完成使用之前自行清理。您当然可以使用BEGIN和END,但一般用法是BEGIN为后续代码设置执行环境,END处理执行后清理。这两者显然具有逻辑关系,即使不必在所有模块中使用该关系。 - Eric Strom


Perl大量借用C和 END  跟随领先 C的 atexit

名称

atexit - 注册一个在进程终止时运行的函数

概要

#include <stdlib.h>

int atexit(void (*func)(void));

描述

atexit() 函数应该注册指向的函数 func,在正常程序终止时无需参数调用。在正常的程序终止时,所有注册的功能都由 atexit() 应按其注册的相反顺序调用函数...


1
2017-08-24 14:09



实际上有一个原因是atexit以它的方式工作。这不是先例。这是一个好主意。 - Ian
@Ian我写了为什么 END 按照它的方式工作,而不是 atexit。 - Greg Bacon
你引用了一个C函数的手册页,然后声称Perl像C一样工作。但是你可以说C就像Perl一样工作。它们只是一个共同的,共享的,好主意的两种表现形式,即你以与构建它们相反的顺序撕下它们。 - Ian