in reply to Confusion about BEGIN block

i am not completely certain i understand BEGIN{} blocks either, but let's take a look.
#!perl -l use strict; use warnings; print "v: $v"; BEGIN{ my $v }
gets us:
Global symbol "$v" requires explicit package name at begin.pl line 4.
BEGIN not safe after errors--compilation aborted at begin.pl line 5.
ok, it's barfing on the print line. looks like the BEGIN declaration isn't getting handled first, or if it is, it's not the right scope. let's try swapping the order of the lines to see if it makes a difference
#!perl -l use strict; use warnings; BEGIN{ my $v } print "v: $v";
gets us
Global symbol "$v" requires explicit package name at begin.pl line 5.
Execution of begin.pl aborted due to compilation errors.
different error. looks like our declaration isn't in scope. let's using "our" as you originally did, and try fully qualifying $v as $::v
#!perl -l use strict; use warnings; BEGIN{ our $v } print "v: $::v";
gets us
Use of uninitialized value in concatenation (.) or string at begin.pl line 5.
v: 
ok, so that works, it just doesn't like the fact that $::v isn't defined. now let's try defining $v outside the begin block
#!perl -l use strict; use warnings; my $v = 5; BEGIN{ $v++ } print "v: $v";
gets us
v: 5
ok, so there's still no problems with scope, but does the BEGIN code even get run? let's try something else
#!perl -l use strict; use warnings; my $v; BEGIN{ $v++ } print "v: $v";
gets us
v: 1
so the BEGIN code is getting run... it looks like BEGIN requires a definition and will use it even if it's in non-BEGIN code, but it gets first dibs on assignment. the reason we got v: 5 is because the assignment = 5 happened AFTER the begin block, even though the declaration and assignment happened in the same statement

fun stuff!

perl -e"\$_=qq/nwdd\x7F^n\x7Flm{{llql0}qs\x14/;s/./chr(ord$&^30)/ge;print"

Replies are listed 'Best First'.
Re^2: Confusion about BEGIN block
by Sandy (Curate) on Oct 15, 2004 at 16:10 UTC
    I think I'm starting to get the hang of this, thankyou.

    I guess my greatest confusion was where and when symbol names needed to be declared. Mmmm.

    I think I understand that

    1. our $var is lexically scoped, and is just an alias for $__PACKAGE::var

    2. because our $var is lexically scoped, when it is in a BEGIN block, it does not mean that the alias (i.e. $var) is available outside of the BEGIN block.

    3. however, if the alias is defined outside the BEGIN block, it will be available for use within the BEGIN block because of the lexical scope if and only if it is declared before the BEGIN block is written

    EXAMPLE #1 works, #2 does not

    #!/usr/bin/perl use strict; our %aa; our $bb; our @cc; print keys %aa,", $bb, @cc\n"; BEGIN {%aa=(1,11); $bb=22; @cc=(3,33); }
    #!/usr/bin/perl use strict; BEGIN {%aa=(1,11); $bb=22; @cc=(3,33); } our %aa; our $bb; our @cc; print keys %aa,", $bb, @cc\n";
    4. all code within the BEGIN block is executed first, regardless of it's location within the file

    5. egads! no wonder I'm confused

      egads! no wonder I'm confused

      It seems you are overthinking this a great deal. The reason strict complains is simple -- it scans the code before anything is executed, and looks for proper scoping. If there is a variable used before it is scoped, strict complains. End of story. Strict does not unravel BEGIN blocks and figure out what will be executed when, it simply looks at the "physical" location of things in the code.