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

merlyn mentioned this in node 23958:
"In 5.6.0, the 'our' keyword is synonymous with 'use vars' to declare package globals."
Uh, no. Not quite. It's use vars but with lexical scoping, so if it's inside a block, it loses effect after the block.

so i decided to do some checking. when i run:
use warnings; use strict; { our $y = 17; print "inner: $y\n"; } print "outer: $y\n";
i get the following warnings:
Variable "$y" is not imported at tester.pl line 10. Global symbol "$y" requires explicit package name at tester.pl line 10 +.
but when i comment out the "use strict", the code runs and i get:
inner: 17 outer: 17
so what happened? it seems like 'our' is similar to 'local' but it inputs the variable into the symbol table. this backs up merlyn's comment that its dynamically scoped. but it appears to stay defined outside of the block its declared in. is this a bug, or a special feature of 'our'?

Replies are listed 'Best First'.
RE: i thought i knew 'our'...
by autark (Friar) on Jul 24, 2000 at 20:39 UTC
    'our' does _not_ declare a lexical scoped variable! What 'our' does is to say that the variables _name_ shall be lexical scoped. so:
    use strict; { our $y = 17; print "inner: $y\n"; } print "outer: $y\n";
    says that you are allowed to use the name '$y' in the block. Its name is lexical scoped. It does enter the name $y into the stash. Now, as you have discovered, without strict you may access $y's value. So, how to do it with strict on ?
    use strict; { our $y = 17; print "inner: $y\n"; } print "outer: $main::y\n";
    strict don't let you use globals (variables that live in the symbol table) unless:
    1. being told that it's actually ok (using 'our' or 'use vars')
    2. you fully qualify its name, as in $main::foo
    So naturally, without strict you may access variables without fully quallifying them as in your last example.

    Autark.

      are you saying that 'our' lexically scopes the name, but globally scopes the value?
        Something like that, yes. Because the variables are put into the symbol table, they are global. In fact, 'our' has no semantical effect unless you use strict vars, so:
        our $foo = 1;
        and
        $foo = 1;
        shouldn't be different at all. It is first when you introduce use strict vars that the our keyword will have a different semantical effect.

        Autark.

Re: i thought i knew 'our'...
by mwp (Hermit) on Jul 25, 2000 at 22:27 UTC

    Just make sure to watch your commas when switching from our($a,%b,@c) to use vars qw($a %b @c).

    Spent days chasing that "bug"... *sigh*

    Alakaboo
    I am the lurker that spams in the night.

Re: i thought i knew 'our'...
by monk (Scribe) on Jul 24, 2000 at 20:58 UTC
    Update: from the man pages i get: An `our' declares the listed variables to be valid globals within the enclosing block, file, or `eval'.
    That is, it has the same scoping rules as a "my" declaration, but does not create a local variable.
    HTH, monk
      'our' and 'my' are two very different beasts. You can not substitute 'our' with 'my' or vice versa, take this as an example:
      use strict; { our $y; $y = 17; print "Inner: $y\n"; } our $y; print "Outer: $y\n";
      That will print:
      Inner: 17
      Outer: 17
      Now, if you substituted our with my (s/our/my/g) then it would print:
      Inner: 17
      Outer:
      ...and it would complain about use of uninitialized variable :-)

      Autark.

        you are right, what i meant was that our could be use to declare variables in the begining
        of a program like:
        #!/usr/bin/perl -w use strict; our($foo,@bar,%args); <- this was what i meant.
        Not to s/my/our/; as you pointed out. Sorry didn't explain myself quite right.
        monk
RE: i thought i knew 'our'...
by jlistf (Monk) on Jul 24, 2000 at 20:23 UTC
    oops... course merlyn said it was lexically scoped, not dynamically scoped. but the question remains the same.