Fellow monks, I need some help because I've found something that makes no sense at all to me.

In case it matters, this is with Perl 5.8.8 (yeah, I'm stuck here although we are trying to get them upgrade to at least 5.10 or 5.14 if we're lucky).

In our CGI code (no mod_perl), we're doing:

use OurCommon;

In OurCommon.pm, we just added:

BEGIN { $main::SIG{__DIE__} = \&OurCommon::handle_fatal_error; # new line ... package OurCommon; } # outside begin and outside a sub

As should be obvious, we're trying to catch fatal errors gracefully to give them an "I'm sorry" page instead of just handing them an ugly "500" page from the web server.

Most of the time, that works just fine.

However, and where I need help understanding just what's going on, sometimes that fails. One CGI file uses Math::BigInt and that module does:

# $lib eq "Math/BigInt/FastCalc.pm" here eval "use $lib qw/@c/;";

However, Math/BigInt/FastCalc.pm doesn't exists and it all goes downhill fast with a fatal error, when the BigInt module is really just probing to see what's there for its use. And in fact, if the DIE handler is commented out, the page happily loads.

In reading about eval, I see that it talks about WARN; we aren't concerned about that.

I also see the statement: "Due to the current arguably broken state of "__DIE__" hooks...". That makes me wonder if we're falling into one of the broken corner cases.

It seemed to me that the obvious solution was to move the assignment to %SIG outside of the BEGIN block to make it the first line of normally executed code (where the comment is outside the block), so the compilation phase wouldn't run it. Alas, it gets called there too! (insert censored words here :)

I thought all "use" statements to load modules (even if they're in a block of code instead of at the top of the file) happened in a conceptual BEGIN at compile time, and the normal statements don't happen until after that. Yet, that isn't the behavior I'm seeing.

The "compile" and run process is (from what I've read):

  1. BEGIN blocks
  2. CHECK blocks
  3. INIT blocks
  4. main code
  5. END blocks

I couldn't find in the Camel book where code in modules outside of Subs and BEGIN is run, but I would have thought it would be like in an implied INIT block. Yet its acting like it's in an implied BEGIN block. So I'm getting the feeling that there is something important I don't understand and I need to.

In fact, testing shows that if I put that assignment in an INIT block, then the code behaves like I expected it to. All the "badness" with BigInt probing is silently ignored and real errors are caught at runtime with no false triggers.

Can anyone help me get my head wrapped around what's going on underneath the covers and why that assignment can't live as a normal line of code in a module?


In reply to SIG, Modules, and Eval by kbrannen

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.