Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

'our' scoping

by Anonymous Monk
on Jun 01, 2004 at 23:04 UTC ( [id://358770]=perlquestion: print w/replies, xml ) Need Help??

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

According to the official documentation, the scope of an 'our' variable should be limited to the file in which it's declared, but that is not the case. Is the documentation wrong, or am I just reading it wrong? The doc says an 'our' is visible across its entire lexical scope, which is defined as the enclosing block, file, or eval. Doesn't that also imply the converse... that it's NOT visible OUTSIDE of its lexical scope? From http://www.perldoc.com/perl5.8.4/pod/func/our.html : 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... ...An our declaration declares a global variable that will be visible across its entire lexical scope, even across package boundaries.

Replies are listed 'Best First'.
Re: 'our' scoping
by blokhead (Monsignor) on Jun 01, 2004 at 23:34 UTC
    our $x;
    I don't see a question either. Lexical scoping rules are pretty straight-forward as to what parts of the code are within some scope, so I bet you are confusing the scope of the variable itself (the value/data that $x points to) and the scope of this name for the variable (the binding).

    With our, we are dealing with package variables, so the variable's data is always accessible (from any namespace) provided we use the fully-qualified name $package::x. our has no scope-induced side effects on the value at $x like local does -- i.e, the value at $x does not disappear when you leave the scope of our $x;.

    What our really does is bind the (shorthand) name $x to the appropriate package variable location. The scope of this name binding is what is lexical, not the lifespan of the package variable or its contents. When you fall out of the scope, you lose access to the package variable via the shorthand name $x and that's it. But its value remains, and you can still get to it with its fully qualified name. Outside the scope, you are free to reuse the name $x for a lexical again.

    It may sound like hair-splitting, but it's this important distinction that will help you understand the different scoping rules.

    blokhead

Re: 'our' scoping
by tilly (Archbishop) on Jun 01, 2004 at 23:31 UTC
    If you're asking this question, then odds are that you wanted my rather our. Not that I'm a fan of our at the best of times, for reasons that Why is 'our' good? make clear.
•Re: 'our' scoping
by merlyn (Sage) on Jun 02, 2004 at 09:58 UTC
Re: 'our' scoping
by dave_the_m (Monsignor) on Jun 01, 2004 at 23:17 UTC
    'our' is just a lexically-scoped compiler directive altering the behviour of 'use strict' for a global variable. The variable is still accessible from all all parts of a program, but within the scope of the 'our' declaration, it is immune from the ravages of 'use strict', eg
    $foo = 1; use strict; { our $foo; $foo++; # $::foo now 2 } { no strict; $foo++; # $::foo now 3 } # dies with # Global symbol "$foo" requires explicit package name $foo++;

    Dave.

      Your description of how our works is subtly wrong. The following demonstrates this, without any strict in the way.
      package foo; our $foo = "I'm in foo"; package bar; our $foo = "I'm in bar"; package foo; print "1) $foo\n2) $foo::foo\n3) $bar::foo\n";
      Note that our caused you to access $bar::foo even when you'd have otherwise expected to access $foo::foo.

      For giggles and grins, mix our with $_ when you aren't in package main. Tons of confusion!

Re: 'our' scoping
by borisz (Canon) on Jun 01, 2004 at 23:21 UTC
    And the question was what? Do not forget that our defines a global var. Maybe you expect what local does?
    Boris
Re: 'our' scoping
by eclark (Scribe) on Jun 01, 2004 at 23:27 UTC

    This is my understanding of our.

    use strict; package foo; our $bar = 1;

    Is the same as...

    use strict; package foo; use vars qw/$bar/; $bar = 1;

    And the same as...

    use strict; $foo::bar = 1;

    And the same as...

    package foo; $bar = 1;

    Sorry for all the strict, but I wanted to show which ones work without a problem in strict. Please correct me if I'm wrong.

      You're wrong :-)

      our makes a lexically scoped alias for a global. That means it remains in scope even if you change the package. Compare:

      use strict; package foo; our $bar = 1; # at this point, using $bar could mean TWO things: # 1) try to access the global $foo::bar # 2) try to access the alias named $bar for $foo::bar # The lexical (second) one wins in perl, so you don't # get a use strict error print $bar; package baz; # Now $bar could mean: # 1) try to access the global $baz::bar # 2) try to access the alias named $bar for $foo::bar # The lexical (second) one still wins. print $bar; # works, prints $foo::bar even though we are in baz
      with:
      use strict; package foo; use vars qw/$bar/; $bar = 1; # $bar has only one meaning, access $foo::bar print $bar; package baz; # $bar has only one meaning, access $baz::bar print $bar; #error

      To answer the original question, the documentation is right, the our (as used in the first code fragment) has no effect outside the file. But... you can still access the global $foo::bar from another file. But this is NOT using the "our" alias as you can for example see by trying to do in that other file:

      package foo; print $bar; # prints the global $foo::bar package baz; print $bar; # prints the global $baz::bar
      The lexical alias is gone, and $bar just accesses the global in the package that is in scope.
        Thankyou thankyou thankyou...

        You have fixed many confusions that I had. I thought that 'use vars' and 'our' were identical, and it did cause me some confusions because some of my code has a mixture of both (pre 5.6 and post 5.6).

        I went back and re-read the our documentation in the camel book and it is very precise, and now I understand (I think) what it is talking about.

        However, when I went back and re-read the use vars documentation in the camel book, I realize the source of my confusion...

        quote (my italics)

        use vars qw($frobbed @munge %seen);
        This pragma, once used to declare a global variable, is now somewhat deprecated in favor of the our modifier. The previous declaration is better accomplished using :
        our ($frobbed, @munge, %seen);
        ...

        No matter which of these you use, remember that they're talking about package globals, not file-scoped lexicals.

        This information had led me astray (it may be technically correct, but it confused me nonetheless).

        In closing, I would be really appreciative if you would turn your post into a mini-tutorial.

        Thanks,

        Sandy

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://358770]
Approved by tinita
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (1)
As of 2024-04-19 00:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found