There are times when you want to do some initialization before any other code is executed. Perl goes further: it gives you a chance to execute code while it is still in the compilation stage.
Normally, while parsing a file, Perl compiles the entire code, and when this process is successfully completed, it starts executing from the first global statement onward. However, if it encounters a subroutine or a block called BEGIN while parsing, it not only compiles it, but also executes it right away, before resuming the compilation of the rest of the file. A small experiment underscores this point:
sub BEGIN { # can also just say BEGIN { }; the word "sub" is optional print "Washington was here \n"; } foo*** ; # Intentional error
This prints the following:
Washington was here syntax error at x.pl line 4, near "** ;" Execution of x.pl aborted due to compilation errors.
Whereas a program with a syntax error normally does not get executed at all, a BEGIN subroutine occurring before the error will be executed.
Because a BEGIN block gets executed even before the compilation phase is over, it can influence the rest of the compilation. If you want to hardcode an include path in your program, here is how to do it:
BEGIN { unshift (@INC, "../include"); } use Foo; # Looks for Foo.pm in "../include" first
An easier approach is to use the lib module that is packaged with the Perl distribution:
use lib qw(../include); # prepends the directory to @INC
Just as you want to do initialization before any other code executes, there are times when you want to do some clean-up after all the code has executed. The END block is called just before the program is due to exit, independent of whether it was a successful exit or not. That is, even if the program dies because of, say, an arithmetic exception, the END block is called anyway. The block is not invoked if the program dies because of an uncaught signal.
BEGIN and END are borrowed from awk . And as in awk , Perl supports multiple BEGIN and END statements. BEGIN statements are executed in the order in which they are seen, while END statements are executed in reverse order of appearance (last in, first out). If there are multiple packages with many BEGIN or END blocks, the order in which the packages were loaded is taken into account.