in reply to Re^4: repeated use of module and EXPORT
in thread repeated use of module and EXPORT

Yeah I saw that text on the perlmod. But I didn't know that use was implicitly a BEGIN... so that makes more sense... But anyone have any links to a more indepth write up of how the compiler works, like how it chooses what to compile first and all that...
  • Comment on Re^5: repeated use of module and EXPORT

Replies are listed 'Best First'.
Re^6: repeated use of module and EXPORT
by shmem (Chancellor) on May 23, 2008 at 20:34 UTC

    It's all in perlmod. Search for BEGIN, UNITCHECK, CHECK, INIT and END. But you should really read it all through.

    There's more to be found in the perl sources... ;-)

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      I just read the whole perlmod you sent, and I guess I was looking at an abridged version previously... It did have much greater detail...

      One thing that seems odd...
      our (@ISA,@EXPORT,@EXPORT_OK); BEGIN { @ISA = qw(Exporter); @EXPORT = qw(debugOn); @EXPORT_OK = qw(); }
      The begin doesn't work without the our before it... is our also implicitly a BEGIN? otherwise I wouldn't think the our should effect the BEGIN block as it shouldn't even get executed until after the BEGIN block is done.

      and finally it didn't explicitly say some things that I think I can infer from the way things appear to function, so correct me if I am wrong on any of the below.
      compilation starts on the top script file...
      Whenever a use, or a require in a BEGIN block (or is require implicitly a BEGIN as well?), or anything of that sort is encountered, it stops processing the current file and switches to that one, and doesn't return until that one is totally complete (as in not just the BEGIN blocks of the second file). And if it hits a use of a module it is already in the middle of processing, all it will do is call that modules import sub, and not try to compile it's code a second time (thus preventing loops).
      Sound right?
      Randell

        The begin doesn't work without the our before it... is our also implicitly a BEGIN?

        Every line of code is compiled. Some of them are executed at least once.

        BEGIN causes code to be executed as soon as it's compiled. That's completely unrelated to the effect of compiling the code in the first place.

        The compile-time effect of most code is to add operations to the execution tree. our's compile-time effect to create a variable. It has no run-time effect (as far as I know).

        Here's another example.

        >perl -le"sub foo { 3 } print foo + 4" 3 >perl -le"sub foo() { 3 } print foo + 4" 7

        Compiling the function modifies the symbol table, which in turns affects how a later statement (print foo + 4;) is compiled. This is independent of when the later statement is executed, so putting it in a BEGIN won't change anything.

        it stops processing the current file and switches to that one, and doesn't return until that one is totally complete

        Yes. Functions and files are executed from top to bottom. Unless you make it not execute from top to bottom.

        (as in not just the BEGIN blocks of the second file)

        Right.

        And if it hits a use of a module it is already in the middle of processing, all it will do is call that modules import sub, and not try to compile it's code a second time (thus preventing loops).

        Not quite. Being "in the middle processing" has nothing to do with it. require and thus use do not execute a file it that has already been executed by require, use or do, or more specifically in %INC.

        The begin doesn't work without the our before it...

        our and my have compile time semantics, like pragmas (e.g. strict). They tell the compiler how to set up the variables declared. That impact might be the same as an implicit BEGIN.

        And if it hits a use of a module it is already in the middle of processing, all it will do is call that modules import sub, and not try to compile it's code a second time (thus preventing loops).

        Sounds right; but it will call the import sub only if it is defined at that point. At compilation, pragmas are evaluated, globs are set up, scopes are built, my variable slots are allocated in that scope's PAD - i.e. all structures needed for execution are created. If at that time an import() subroutine has yet been allocated in a typeglob slot, it will be called. I'm not sure about whether that import() call triggers a compile at that point, or if it has been compiled previously - but I guess the former. Anyways, some code that uses some other code which is just being compiled sees whatever has been defined in that other code's name space at that moment.

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}