in reply to BEGIN vs initialization

The general idea is that perl compiles the entire 'unit' (typically a file, or a string eval), then execute it. There are two exceptions:
  1. A BEGIN block. The block is run right after it is compiled. The block is compiled entirely before it's run.
  2. A use statement. This one is run as soon as it's compiled. One might see a use statement as a require and an import call inside a BEGIN block. The side-effect of a use statement is that the used module is compiled and executed.
So, it your case, the order is (ignoring all the other modules):
  1. Compile main up to the 'use Gbl;' line.
  2. Run 'use Gbl;'. This causes:
    1. Compile Gbl.pm.
    2. Run the code in the Gbl package.
    3. Call 'Gbl->import' (if Gbl::import is defined).
  3. Compile the BEGIN block.
  4. Execute the code in the BEGIN block.
  5. Compile the rest of main.pl.
  6. Run main.pl (except the already run use statements and BEGIN blocks).

Replies are listed 'Best First'.
Re^2: BEGIN vs initialization
by Wiggins (Hermit) on Dec 01, 2009 at 01:31 UTC
    I did go through the 'perlmod' to find the part about BEGIN executing as soon as parsed (before the rest of the file is parsed). Your explanation describes a set of events that answers all my questions.

    Step 2.2 (execute Gbl) takes place before returning to parse more of the main.pl! Therefore the variables will hold valid definitions when main's BEGIN block used them.

    I was picturing that in the absence of BEGIN and CHECK sort of diversions, that the entire file structure (including all the 'use' modules) would be assembled/parsed, then executed starting back at the top. That is a holdover from the old 'C'/cpp days.

    That also explains why BEGIN blocks execute during a "perl -c main.pl" syntax checking run.

    Thanks for a the concise answer to my fundamental question..

    It is always better to have seen your target for yourself, rather than depend upon someone else's description.

      I did go through the 'perlmod' to find the part about BEGIN executing as soon as parsed

      If you didn't realize that, then I'm curious as to why you placed parsing Glb first in both scenarios? It seems to indicate you knew use Glb; was executed as soon as it was parsed.

      If you knew that, the key point you were really missing was that require and thus use execute the module as any other script. It gets parsed and executed. That's got nothing to do with BEGIN.