As I understand these special functions inside Perl code, BEGIN and CHECK blocks run during the compilation phase while INIT and END blocks run during actual execution phase.
I can understand using these blocks inside actual Perl code (Perl libraries) but what about using them inside modules? Is that possible?
Since when we use use <Module-name>
the module is compiled, so in effect BEGIN and CHECK blocks run. But how will the INIT and END blocks run since module code I don't think is run in the true sense. We only use certain functions from inside the modules.
Short The special code blocks in packages loaded via use
are processed and run (or scheduled to run) as encoutered, in the same way and order as in main::
, since use
itself is a BEGIN
block.
Excellent documentation on this can be found in perlmod . From this section
A BEGIN code block is executed as soon as possible, that is, the moment it is completely defined, even before the rest of the containing file (or string) is parsed.
Since the use
statements are BEGIN
blocks they run as soon as encountered. From use
It is exactly equivalent to
BEGIN { require Module; Module->import( LIST ); }
So the BEGIN
blocks in a package run in-line with others, as they are encountered. The END
blocks in a package are then also compiled in the same order, as well as the other special blocks. As for the order of (eventual) execution
An
END
code block is executed as late as possible ...
and
You may have multiple END blocks within a file--they will execute in reverse order of definition; that is: last in, first out (LIFO)
The order of compilation and execution of INIT
and CHECK
blocks follows suit.
Here is some code to demonstrate these special code blocks used in a package.
File PackageBlocks.pm
package PackageBlocks;
use warnings;
BEGIN { print "BEGIN block in the package\n" }
INIT { print "INIT block in the package\n" }
END { print "END block in the package\n" }
1;
The main script
use warnings;
BEGIN { print "BEGIN in main script.\n" }
print "Running in the main.\n";
INIT { print "INIT in main script.\n" }
use PackageBlocks;
END { print "END in main script.\n" }
BEGIN { print "BEGIN in main script, after package is loaded.\n" }
print "After use PackageBlocks.\n";
Output
BEGIN in main script. BEGIN block in the package BEGIN in main script, after package is loaded. INIT in main script. INIT block in the package Running in the main. After use PackageBlocks. END in main script. END block in the package
The BEGIN
block in the package runs in order of appearance, in comparison with the ones in main::
, and before INIT
. The END
block runs at end, and the one in the package runs after the one in main::
, since the use
comes before it in this example.
This is very easy to test for yourself
use Module
(and require EXPR
and do EXPR
and eval EXPR
) compile the Perl code and then immediately run it
That is where the 1;
at the end of most modules is picked up. If executing the module's code after compiling it doesn't return a true value then require
will fail
Admittedly there usually isn't much use for an INIT
or an END
block, because the run-time phase is so intimately tied to the compilation, and because modules are generally about defining subroutines, but the option is there if you want it
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.