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

hi,
# test.pl #/usr/bin/perl use strict; use warnigns; BEGIN { use FindBin qw($RealBin); use lib "$RealBin/lib/"; $ENV{APP_ROOT} = $RealBin; } use MyApp::Conf qw/APP_NAME/; ... ...
then i have :
package MyApp::Conf; BEGIN { # do something with $ENV{APP_NAME} }
when i run test.pl , MyApp::Conf error on undefined $ENV{APP_NAME}.. why is that?

Replies are listed 'Best First'.
Re: BEGIN block question
by FunkyMonk (Bishop) on Jun 05, 2007 at 21:45 UTC
    From permod:

    A BEGIN code block is executed as soon as possible, that is, the moment it is completely defined, even before the rest of the containing file (or string) is parsed.

    Your BEGIN block in test.pl is executed before your use MyApp::Conf qw/APP_NAME/; statement

      you seemed to refer to the code that has use MyApp::Conf qw/APP_NAME/; outside the BEGIN block. in that case, after the BEGIN block run, $ENV{APP_NAME} is set and use MyApp::Conf qw/APP_NAME/; runs fine.

      it is only problem whei put use MyApp::Conf qw/APP_NAME/; inside the block as the last line.

        While everything I wrote is correct, it just didn't answer your question at all. Sorry.
Re: BEGIN block question
by Anonymous Monk on Jun 05, 2007 at 21:41 UTC
    sorry. the above code actually works. it failed when i put the use MyApp::Conf qw/APP_NAME/; inside the BEGIN block.

      The reason it fails inside the BEGIN block is that the use of MyApp::Conf happens while the BEGIN block is being compiled, but the assignment to %ENV happens after the BEGIN block is compiled (i.e., at the BEGIN block's "run time"). If you put it after the BEGIN block, then the compilation (use) of MyApp::Conf happens after the BEGIN block has executed (and the assignment to %ENV has happened).

        thank you. that's very clear. i totally forgot that assignment happens at runtime and use happens at compiled time. hence the failure in the BEGIN block.

      This came up twice very recently. The problem is that the use statements in the BEGIN block finish compiling before the BEGIN block does (seeing as the BEGIN block finishes later in the sources), so they get executed first.

      In short, you want

      use FindBin qw($RealBin); use lib "$RealBin/lib/"; BEGIN { $ENV{APP_ROOT} = $RealBin; } use MyApp::Conf qw/APP_NAME/;

      Previous thread #1
      Previous thread #2