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", };

In reply to Re: Use of BEGIN block by stevieb
in thread Use of BEGIN block by harangzsolt33

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.