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

Dear monks, I need some guidance on the special code blocks BEGIN/END/INIT/et al, especially INIT.

1. Does Perl provide a simple way to find out in which phase a code is running in, or do I have to resort to some trickery like analyzing special vars (because IIANM perlvar mentions that some vars are only available at compile-time), or inserting our own BEGIN/END/INIT blocks to set some flags?

2. Is it possible to insert an INIT block conditionally? That is, insert it if it's not too late, otherwise don't bother?

The situation I'm facing ATM: I have a module (M1) which is usually loaded via use() (thus, compile-time). This module inserts an INIT block to run its init(). The reasons for this: 1) to let other modules load first and possibly alter M1's configuration before init() is run; 2) to run init() automagically without user needing to call it, thus giving convenience; 3) to avoid running init() under 'perl -c'.

However, for a modular command-line application that I'm writing right now, where to reduce startup overhead I load selected modules depending on which subcommand is given on the command line, M1 is now loaded via require() in the runtime phase. This results in "Too late for INIT block" error message. To shut up this error message, I can instead run everything in the BEGIN block (e.g. by wrapping BEGIN { ... } for the whole application) but then M1's INIT block will never be called in time anyway. And upon error Perl also emits an annoying extra message: "BEGIN failed--compilation aborted" since every error is a compile-time error now.

So my choice now is to remove M1's INIT block, thus requiring M1's user to init() manually. Sadly this breaks all the other use cases. But suppose M1 can insert INIT block conditionally, that'd be much nicer. I'm open to other suggestions.

Replies are listed 'Best First'.
Re: More about the INIT code block
by dgaramond2 (Monk) on Jan 25, 2011 at 15:58 UTC
    Sorry, didn't find this black magic when googling earlier from my phone. So turns out I can still run INIT block on runtime. At least this solves my current problem.