in reply to What is the scope of BEGIN? Or... when does it "begin?"

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

Replies are listed 'Best First'.
Re^2: What is the scope of BEGIN? Or... when does it "begin?"
by argv (Pilgrim) on May 06, 2005 at 05:21 UTC
    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.
        Keep in mind that environment variables are not yet set at the time of BEGIN
        I'm not sure what you mean by that.
        $ perl -we'BEGIN{print $ENV{MANPATH}}' /usr/man:/usr/local/man:/usr/share/man:/usr/autotool/devel/man:
        Here's code that illustrates the question. I start with "Foo.pm":

        # Foo.pm my $shell = $ENV{'SHELL'} || ""; BEGIN { if ( $ENV{'SHELL'}) { print "\$ENV{'SHELL'} is $ENV{'SHELL'}...\n"; } else { print "\$ENV{'SHELL'} is not set...\n"; } if ( $shell ) { print "\$shell is $shell...\n"; } else { print "\$shell is not set...\n"; } } 1;

        Now, the perl script, "foo" has nothing but:

        #!/usr/bin/perl use Foo; print "done.\n";

        Running the program should be self-explanitory. The question is: if "use" is an implicit BEGIN, and there is no precedence to the orders of the BEGIN blocks, then why isn't "$shell" set outside of the BEGIN block on Foo.pm?

        And, as far as Randall's comment about environment variables not set at the time of BEGIN, then what explains the behavior of this sample program?

      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

Re^2: What is the scope of BEGIN? Or... when does it "begin?"
by bart (Canon) on May 07, 2005 at 11:48 UTC
    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.