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

Consider the following:

#!/usr/bin/perl use Bar; BEGIN { print "Testing\n"; } print "this is a test.\n";

I would expect to see "Testing" before it does anything else. But, if Bar.pm has nothing but a single print statement, I see that output before the "Testing" statement is printed. Hence, I'm confused by the following from the perl documentation:

Execution order: BEGIN{}, (possible save of state through compiler back-end), INIT{}, program runs, END{}.

Isn't the "print" statement in Bar.pm part of the "program runs" step in the above sequence?

Replies are listed 'Best First'.
Re: What is the scope of BEGIN? Or... when does it "begin?"
by tlm (Prior) on May 06, 2005 at 04:55 UTC

    use Bar is equivalent to

    BEGIN { require Bar; Bar->import(); }
    If Bar.pm contains top-level statements, like the print statement you cite, they will get executed during the require. Since this all happens in a BEGIN block that appears before the BEGIN that contains the print "Testing\n" statement, you will see its effects earlier. See use.

    the lowliest monk

      Ok, if that's the case, why am I NOT getting the proper behavior described in Re^3: How to conditionally use CGI::Carp??

      That is, the perl module contains code that sets a variable, and then a BEGIN block tests that variable. So, why can't I assume that the variable is set since (as you said above), the module was included using "use", which means it's like it's in a BEGIN? I take it that BEGINs can be nested.... which I think is the only explanation...

        I've read every message in this thread and the referenced thread. I've yet to see any code that would behave differently than I expect. However, you're still referring to behavior that "seems odd". Can you post the precise code that puzzles you, so we can follow along better than just some handwaving?

        Keep in mind that environment variables are not yet set at the time of BEGIN, which also means they aren't set at the time of any use. If you're setting variables based on that, you'll be very confused.

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.


        update: oops, misremembering about %ENV not being set at compile time. I wonder what it is that I was doing that made me misremember that.

        Sorry, I really can't follow your argument. Could you please show some concrete code (all in one place)? In particular, I would like to know (1) what module contains what variable-initialization code that is tested in a BEGIN block; and (2) where exactly is this BEGIN block relative to the use or require statement responsible for loading the module.

        the lowliest monk

      Let me add that the reason why use is executed as if in a BEGIN block, thus before the rest of the script is compiled, is because what the module does may change the meaning of the rest of the program. Think of pragmas, like strict and integer, or think of constant, where the meaning of a bareword in your source changes, because it was defined as a subroutine in the module. The same thing easily happens in modules you wrote yourself, hence defining a subroutine in your module alleviates the need to use parens in your scripts.
Re: What is the scope of BEGIN? Or... when does it "begin?"
by Ben Win Lue (Friar) on May 06, 2005 at 08:10 UTC
    I am puzzled, too. So far I did things like:

    use strict; BEGIN{unshift (@INC,"\\mylib");} use mylib1;
    Which worked perfectly. After reading argvs node, I tested:

    use strict; use mylib1; BEGIN{unshift (@INC,"\\mylib");}
    Which produced an error. So far I thought BEGIN{} would be executed always before anything else...
      See tlm's reply above. use is impicitly wrapped in a BEGIN. And since BEGIN's have no precedence over each other, your second example is effectively:
      BEGIN { require mylib1; mylib1->import(); unshift (@INC,"\\mylib"); }
      (I left out 'use strict' for simplicity's sake).