Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

For some reason I can't find a good explanation of the order of module compilation and execution. For example if A.pm uses B.pm, and scripl.pl uses both A.pm and B.pm, what is the order of compilation? If 2 modules have dependencies on each other an they both do some initialization before defining subs, how can your guarantee which order the initialization code is run in? Thanks.
  • Comment on Understanding order of module compilation and execution

Replies are listed 'Best First'.
Re: Understanding order of module compilation and execution
by Perl Mouse (Chaplain) on Dec 16, 2005 at 17:00 UTC
    They are executed in order of appearance, with the additional requirement that modules that are 'used' appear when the compiler passes by, and modules that are 'required' appear during run time.

    So, if the script has "use A;" before "use B;", the compiler will complile "A" first (and during that compilation, it will compile any 'used' modules in A), then, when it has compiled A, it will compile B.

    If 2 modules have dependencies on each other an they both do some initialization before defining subs, how can your guarantee which order the initialization code is run in?
    It would be a lot easier if you don't have circular dependencies. One day, you, or someone coming after you, will change the code that requires A to be compiled before B, while at the same time, it requires B to be compiled before A.

    Anyway, you will have to use BEGIN and INIT blocks, remembering that 'use' is a BEGIN block as well. BEGIN blocks are executed as soon as they are compiled. INIT blocks are run before the main program starts, and they are run in the order they are compiled in.

    Perl --((8:>*
      So, if the script has "use A;" before "use B;", the compiler will complile "A" first (and during that compilation, it will compile any 'used' modules in A), then, when it has compiled A, it will compile B.

      Not quite. The compiler may *start* compliling "A" first, but it will not necessary compile all of "A" first. Even without using circular references.

      # main.pl use ModA; use ModB; # prints B A 1;
      # ModA.pm package ModA; use ModB; print("A\n"); 1;
      # ModB.pm package ModB; print("B\n"); 1;
        The compiler may *start* compliling "A" first, but it will not necessary compile all of "A" first.
        What do you think my and during that compilation, it will compile any 'used' modules in A means?
        Perl --((8:>*
Re: Understanding order of module compilation and execution
by BrowserUk (Patriarch) on Dec 16, 2005 at 16:53 UTC

    You can arrange for your initialisation to occur in a specific order, by the use of BEGIN blocks within the modules and careful arrangement of the ordering of the use statements in the calling code. Basically, BEGIN blocks are called in the order they are seen, so if both A.pm & B.pm have BEGIN blocks, they will get called in whichever order their use statements appear in script.pl.

    See Perlmod for the nitty gritty details.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Understanding order of module compilation and execution
by xdg (Monsignor) on Dec 16, 2005 at 17:21 UTC

    Why not experiment and see what happens? E.g.

    A.pm

    package A; BEGIN { print "compiling A\n" } print "executing A\n"; 1;

    Z.pm (Not B since there is a B module already)

    package Z; BEGIN { print "compiling Z\n" } print "executing Z\n"; 1;

    script.pl

    use strict; use warnings; BEGIN { print "compiling script.pl\n" } use A; use Z; print "executing script.pl\n";

    result of running script.pl

    compiling script.pl compiling A executing A compiling Z executing Z executing script.pl

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Understanding order of module compilation and execution
by ikegami (Patriarch) on Dec 16, 2005 at 17:00 UTC
    If ModA uses ModB and ModB uses ModA, you'll have problems exporting symbols. The best way I've found is to do:
    # ModA.pm use strict; use warnings; package ModA; BEGIN { our @ISA = qw( Exporter ); our @EXPORT_OK = qw( ... ); require Exporter; } use This; use ModB; use That; ... 1;
    # ModB.pm use strict; use warnings; package ModB; BEGIN { our @ISA = qw( Exporter ); our @EXPORT_OK = qw( ... ); require Exporter; } use This; use ModA; use That; ... 1;

    Otherwise, things usually work out fine.