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

I am curious, why does the position of use strict matter in the code below?
$ perl -e 'BEGIN{use strict; our $c=1} print $c' 1 $ perl -e 'use strict; BEGIN{our $c=1} print $c' Variable "$c" is not imported at -e line 1. Global symbol "$c" requires explicit package name at -e line 1. Execution of -e aborted due to compilation errors.
If I declare a variable in early stages like BEGIN or INIT then shouldn't the scope be there in the later stages too?

Replies are listed 'Best First'.
Re: BEGIN blocks and use stict positioning
by Fletch (Bishop) on Apr 20, 2006 at 18:19 UTC

    Your problem is that the strict pragma is lexically scoped. You've enabled it within the BEGIN block, but once that block terminates it reverts back to the default (i.e. off). Not to mention that our declarations are likewise lexically scoped and similarly in your second example the declaration of $c disappears once the BEGIN block is over.

Re: BEGIN blocks and use stict positioning
by Jenda (Abbot) on Apr 20, 2006 at 18:19 UTC

    Both use strict; and our affect only the rest of the enclosing block! So in the first case you turned the strictures on only for the rest of the BEGIN{} block, declared that you are going to use the package variable $main::c under the short name $c and then, with no strictures, accessed the $main::c and printed the value you specified in the BEGIN{} block.

    In the second case the strict affects the rest of the script, so because the our only declares the $c for the rest of the BEGIN block, strict doesn't allow you to use the short name $c and you get an error.

Re: BEGIN blocks and use strict positioning
by ikegami (Patriarch) on Apr 20, 2006 at 21:58 UTC
    Given the explanations, here are possible solutions:
    perl -e 'use strict; our $c; BEGIN{ $c=1 } print $c'
    perl -e 'use strict; BEGIN{ our $c=1 } our $c; print $c'
    perl -e 'use strict; BEGIN{ our $c=1 } print our $c'
Re: BEGIN blocks and use strict positioning
by davido (Cardinal) on Apr 20, 2006 at 22:00 UTC

    Read the documentation for our:

    our associates a simple name with a package variable in the current package for use within the current scope. When use strict 'vars' is in effect, our lets you use declared global variables without qualifying them with package names, within the lexical scope of the our declaration. In this way our differs from use vars , which is package scoped.

    That means, despite the fact that our creates a package global, it is created for use within the current lexical scope. But it's still a package global. Strictures balks at the use of $c outside of the BEGIN{} block. But that too is only if strictures is effect in the lexical scope in which it is being violated. Since your first example breaks strictures, but does so outside of the scope in which strict is in effect, you get no complaint. The second example breaks strictures, and does so within the same scope in which strictures is effect, so you get a complaint.


    Dave