in reply to Use of BEGIN block

Since you already know what a begin block does, I won't explain that. I will explain why it is needed. Take this code:

use warnings; use strict; my $v = 5; use constant { TEST => $v, }; print TEST;

...and output:

Use of uninitialized value in print at begin.pl line 10.

What happens there is that the use compile is a compilation operation whereby the $v variable assignment is a runtime one. In the above case, the use compile is compiled but since runtime is done after compile and hasn't happened yet, $v is undefined. Using a BEGIN block we can avoid this. BEGIN blocks are processed as they are seen in the file, which is generally why they occur at the top of a file.

The above example is exceptionally basic. Imagine you need $v to be populated by a configuration file accessed via a function or some such. This was the most basic use of BEGIN my non-caffinated brain could come up with, but I've used it and the other named blocks (mentioned below) for many complex tasks over the years.

my $v; BEGIN { $v = 5; } use constant { TEST => $v, }; print TEST;

We must declare the variable outside of the BEGIN block (or it won't be visible outside that block), then assign its value inside of BEGIN.

If you move the BEGIN block to below the use compile line, it'll break again because of the previously mentioned FIFO reading. END blocks are done in reverse order. They are processed last seen, first processed.

There are five named blocks in Perl, BEGIN, UNITCHECK, CHECK, INIT and END. They are all executed at precise phases before, during and after the compile phase (and in the case of END, after your program terminates), and can be used to execute specific code and perform special tasks to set your application up, or again, in the case of END, to clean it up after it's done.

Further reading.

Update: Here's a production use of the example I used above, snipped and cleaned for brevity. The AUTH_CACHE_FILE wouldn't work if the $home_dir assignment wasn't done in BEGIN.

my $home_dir; # The %api_cache hash is a cache for API call data across all objects. # It is managed by the _api_cache() private method. Each cache slot co +ntains the # time() that it was stored, and will time out after # API_CACHE_TIMEOUT_SECONDS/api_cache_time() my %api_cache; BEGIN { $home_dir = File::HomeDir->my_home; } use constant { DEBUG_CACHE => $ENV{DEBUG_API_CACHE}, API_CACHE_PERSIST => 0, API_CACHE_TIMEOUT_SECONDS => 2, API_TIMEOUT_RETRIES => 3, AUTH_CACHE_FILE => "$home_dir/api_auth_cache.json", };