views:

82

answers:

3

I have no deep or interesting question--I'm just curious why it is so.

+6  A: 

Each package is assumed to rely on the correct function of EVERYTHING that went before it. END blocks are intended to "clean up and close out" anything the package might need to take care of before the program finishes. But this work might rely on the correct functioning of the packages started earlier, which might no longer be true if they are allowed to run their END blocks.

If you did it any other way, there could be bad bugs.

Ian
+5  A: 

Here is a simple example which may help:

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

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

This outputs: ([])

If END had been a FIFO then BEGIN/END wouldn't work well together.

Update - excerpt from Programming Perl 3rd edition, Chapter 18: Compiling - Avant-Garde Compiler, Retro Interpreter, page 483:

If you have several END blocks within a file, they execute in reverse order of their definition. That is, the last END block defined is the first one executed when your program finishes. This reversal enables related BEGIN and END blocks to nest the way you'd expect, if you pair them up

/I3az/

draegtun
This sorta begs the question. You create a situation where BEGIN and END blocks have to fire in the order you want to explain why they should fire in the order you want. However, there's no a priori reason that you have to have, or even should, have both working together.
brian d foy
@brian d foy => This is obviously a simple example, but imagine each of those BEGIN/END pairs were in separate modules, and module 2 depends on module 1, in its end block. If it were FIFO, module 1 would clean itself up before module 2 was done using it. You can of course use BEGIN and END however you want, but the general usage is BEGIN sets up the execution environment for the subsequent code, and END handles post execution cleanup. The two clearly have a logical relation, even if that relation does not have to be used in all modules.
Eric Strom
+1  A: 

Perl borrows heavily from C, and END follows the lead of C's atexit:

NAME

atexit - register a function to run at process termination

SYNOPSIS

#include <stdlib.h>

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

DESCRIPTION

The atexit() function shall register the function pointed to by func, to be called without arguments at normal program termination. At normal program termination, all functions registered by the atexit() function shall be called, in the reverse order of their registration …

Greg Bacon
There's actually a reason atexit works the way it does. It's not about precedent. It's about a good idea.
Ian
@Ian I wrote about why `END` works the way it does, not `atexit`.
Greg Bacon
You quoted a man page for a C function, and then claimed that Perl worked like C. But you might as well say that C works like Perl. They are just two manifestations of a common, shared, good idea, which is that you tear things down in the opposite order that you build them up.
Ian