I am seeking to expand my understanding of the interplay between BEGIN and END blocks, strictures and scoping.

Assume that I have on my system a file C:/shb.

Let's call this Case 1:

# perl BEGIN { $shbstatus = (-f "C:/shb") ? 1 : 0; } END { $shbstatus ? print "shb identified\n" : print "shb was not identified\n"; } use warnings; print "XYZ\n"; print "$shbstatus\n";

I expect the output to be ...

XYZ 1 shb existed

... and indeed it is.

Case 2: I modify the variable declared inside the BEGIN block to make it private.

# perl BEGIN { my $shbstatus = (-f "C:/shb") ? 1 : 0; }

Since $shbstatus is now private to the BEGIN block, I expect the output to be ...

XYZ Use of uninitialized value in concatenation (.) or string at begin.pl +line 15. shb was not identified

... and so it is. C:/shb still exists; it just wasn't identified.

Case 3: I restore the variable declared inside the BEGIN block to global status, but apply strictures before the BEGIN block.

# perl use strict; BEGIN { $shbstatus = (-f "C:/shb") ? 1 : 0; }

Part of me says, "$shbstatus is inside a BEGIN block, which gets executed first, so it won't throw an error." Another part of me says, "No, use strict precedes the BEGIN block in the file, so $shbstatusmust be qualified." It turns out that the latter is correct, as the output is:

Global symbol "$shbstatus" requires explicit package name at begin.pl +line 4. BEGIN not safe after errors--compilation aborted at begin.pl line 5. shell returned 9

Case 4: But now I put use strict inside its own BEGIN block which precedes that containing $shbstatus.

Update: I should have included this for clarity:

# perl BEGIN { use strict; } BEGIN { $shbstatus = (-f "C:/shb") ? 1 : 0; }

Frankly, I wouldn't have expected the output in this case to be any different from Case 3. To my surprise, everything compiles and prints nicely:

XYZ 1 shb identified

... which implies that the global variable $shbstatus was not restricted by the use strict call inside the first BEGIN block.

Why not?

(I should add that my goal here is to write a test file that first tests for the existence of a file on disk, then does one thing if the file is present (temporarily rename it) and a different thing if it is not (create it), then makes sure that the presence or absence of the file on the disk is unchanged at the end of the test notwithstanding any dies or croaks in the interim. I've read perlmod and perlsub but am still not entirely clear.)

Thanks in advance.

Jim Keenan


In reply to BEGIN and END blocks, use strict and scoping by jkeenan1

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.