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

Greetings, monks. I often use BEGIN blocks to check that any required environment variables are set correctly. This prevents the body of the module or script from needing to worry about whether or not the settings are correct. However, when I call croak() or die() from within a BEGIN block, Perl appends a confusing error message after my die() text, like:

BEGIN failed--compilation aborted at /home/sam/xxx/lib/XXX/Script.p +m line 117. Compilation failed in require at bin/yyy_loader line 93. BEGIN failed--compilation aborted at bin/yyy_loader line 93.

This happens even when I call die() with a string ending in a new-line, which usually inhibits the call trace. Seeing this stuff about failed compilation gives my users an excuse not to read the error message patiently explaining that they need to set an environment variable to run the script.

Does anyone know how to avoid this aside from abandoning BEGIN blocks?

-sam

Replies are listed 'Best First'.
Re: BEGIN and die(), an ugly combination
by hv (Prior) on Feb 06, 2004 at 18:12 UTC

    It is possible simply to warn() and exit() - this will avoid additional messages for perl-5.6.0 and later:

    zen% /opt/perl5.005_03/bin/perl -wle 'BEGIN { warn "foo\n"; exit 1; }'
    foo
    Callback called exit at -e line 1.
    BEGIN failed--compilation aborted at -e line 1.
    zen% /opt/perl-5.6.0/bin/perl -wle 'BEGIN { warn "foo\n"; exit 1; }'
    foo
    zen% 
    

    Hugo

      *ding ding ding* We have a winner. Not quite as concise as die(), but much better than print STDERR and POSIX!

      Thanks! -sam

Re: BEGIN and die(), an ugly combination
by Fletch (Bishop) on Feb 06, 2004 at 17:49 UTC

    Kinda kludgy, but you could print to STDERR and use POSIX::_exit to bail immediately rather than using die.

    Update: Yes, the point of POSIX::_exit was that it works all the way back to 5.005_03.

    $ /usr/bin/perl5.00503 -MPOSIX=_exit -e 'BEGIN { print STDERR "Floobl +e!\n"; _exit( 1 ); } print "zorch\n"' Flooble! $
      That's a good idea. You're suggesting POSIX::_exit() because exit() will also produce the BEGIN failure error, right?

      -sam

        When I try it, exit() doesn't give the extra BEGIN failed messages, so using warn/exit will probably do what you want (unless multithreading).
Re: BEGIN and die(), an ugly combination
by ctilmes (Vicar) on Feb 06, 2004 at 17:52 UTC
    use POSIX:
    use POSIX qw(_exit); BEGIN { print STDERR "my error message\n"; _exit(-1) }
    Update: Actually, normal exit works fine too:
    BEGIN { warn "my error message\n"; exit -1 }