in reply to Confusion about BEGIN block

Your confusion is with respect to the scoping that our creates. ...yes, scoping, believe it or not. See the documentation for our.

our is indeed creating those symbols, and they live for the duration of the script (unless you delete them from the package-global symbol table). But for the purposes of strictures, their access is limited to the enclosing block in which they were created. You could still get at them outside the BEGIN block by using their fully qualified name (ie, $main::bb), since this doesn't raise the red flag for strictures, or declare them within the BEGIN block via the "use vars" pragma instead of our.


Dave

Replies are listed 'Best First'.
Re^2: Confusion about BEGIN block
by Sandy (Curate) on Oct 15, 2004 at 15:54 UTC
    thankyou, I had forgotten about the scoping of "our".

    From the Camel Book, it says "In this respect (referring to the scoping of our) it differs from  use vars, which affects the entire package and is not lexically scoped.

    I tried

    #!/usr/bin/perl use strict; print keys %aa,", $bb, @cc\n"; BEGIN {use vars qw(%aa $bb @cc); %aa=(1,11); $bb=22; @cc=(3,33); }
    and it still complained. Is this because use strict truly insists on the our and/or my for all symbols?

    Sandy

      The strict check has a compiletime component to it. BEGIN blocks are guaranteed to be executed prior to anything else in the script, but they are compiled alongside the rest of the script, as they are seen, as the script is compiled line by line. In your script, 'print' is seen and compiled before your BEGIN block, and though the BEGIN block is executed before your 'print', the deed is already done; the compiler with strictures turned on has noticed that you have referred to a variable that hasn't been seen/declared yet. Yes, BEGIN executes first, but it is seen by the compiler in sequential order as the script is parsed top to bottom.

      Using the use vars pragma as I suggested solves your scoping issues, but it doesn't change the fact that at compiletime, with the use strict pragma in place, the compiler is seeing a variable getting used before it is seeing the variable being declared. That's where you need to change your order, or move the "our" to outside the BEGIN block.


      Dave

      You can use:
      #!/usr/bin/perl use strict; our (%aa, $bb, @cc ); print keys %aa,", $bb, @cc\n"; BEGIN {%aa=(1,11); $bb=22; @cc=(3,33); }
      Boris