Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

my() and our()

by dsb (Chaplain)
on Aug 09, 2005 at 14:30 UTC ( #482218=perlquestion: print w/ replies, xml ) Need Help??
dsb has asked for the wisdom of the Perl Monks concerning the following question:

From the docs:
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.
...
An "our" declaration declares a global variable that will be visible across its entire lexical scope, even across package boundaries. The package in which the variable is entered is determined at the point of the declaration, not at the point of use.

Given that explanation, I would've thought you could use our() to localize a variable. If our() has the same scoping rules as my(), then I would've thought that the following two snippets result the same.

$var = 1; { my $var = 2; print $var, "\n"; # prints 2 } print $var, "\n"; # prints 1
and
our $var = 1; { our $var = 2; print $var, "\n"; # prints 2 } print $var, "\n"; # also prints 2
But they don't, and I can't understand why. I'm guessing that it has something to do with the fact the second our() declaration clobbers the first, but that assumption seems to ignore the scoping rules that the docs say are the same as my().

Anyone?


dsb
This @ISA my cool %SIG

Comment on my() and our()
Select or Download Code
Re: my() and our()
by merlyn (Sage) on Aug 09, 2005 at 14:40 UTC
Re: my() and our()
by Joost (Canon) on Aug 09, 2005 at 15:19 UTC
Re: my() and our()
by bunnyman (Hermit) on Aug 09, 2005 at 15:25 UTC

    The second "our" does create a new lexical variable, but it is aliased to the package variable. Effectively, it is the same variable.

    If you wanted to localize it, you need to use "local".

    In practice, it would be very rare to find code using "our" inside a block. It is typically used at the top of the file, because it declares (package) global variables.

    Even if you did use "our" inside of a block, it just gives you access to the global variable for that block only.

    Note: None of this really matters until you say "use strict". Without strict, you can use global variables anywhere. With strict, you must use "our" to declare the variables.

      There are actually uses (well, at least one that I can think of) for our beyond use 'strict' context. I have had occasion to use our at the top of a file that contained multiple packages so that I could have a package global that was accessible without full qualification throughout the file. E.g.:

      package X; our $global = 'Xglobal'; ... more stuff here ... package Y; print $global;

      When run, this code prints Xglobal even though the reference to $global is in package Y's space and it was defined as being a global in package X. The our makes all unqualified references to the variable be assumed to be in the X package namespace even after you move into a different namespace. The same effect can be obtained with my(), except that then the variables are not accessible to other perl code that uses/requires this code.

      --DrWhy

      "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

Re: my() and our()
by revdiablo (Prior) on Aug 09, 2005 at 15:49 UTC
    If our() has the same scoping rules as my()

    The scoping rules are only the same in terms of where the variable is accessible. Meaning you can only access a lexical variable within the current lexical scope. Outside of that, you will get an error (if you're using strict). The rules aren't the same when it comes to how long the variables live, as you've discovered.

Re: my() and our()
by emazep (Priest) on Aug 09, 2005 at 16:28 UTC
    A simple package declaration addition to your code will produce the result you expect:
    our $var = 1; { package Inner; # new package declaration our $var = 2; print $var, "\n"; # prints 2 } print $var, "\n"; # prints 1, # cause we're back in the "outer" package # (main, by default)
    This is just a little example that may help to clarify what the other eminent monks have already explained in this thread.

    Ciao,
    Emanuele.

Re: my() and our()
by xdg (Monsignor) on Aug 09, 2005 at 18:48 UTC

    And if the othe various posts haven't illuminated yet, it's worth walking through some other examples step by step. (Including strict and warnings.)

    Using all fully qualified globals:

    use strict; use warnings; $main::var = 1; { $main::var = 2; print $main::var, "\n"; # prints 2 } print $main::var, "\n"; # also prints 2

    Declaring within the block:

    use strict; use warnings; $main::var = 1; { our $var = 2; print $var, "\n"; # prints 2 } print $main::var, "\n"; # also prints 2

    Declaring within the block and trying to use unqualified later (on line 9) causes a compile-time error under strict -- the "our" only has its effect of allowing use of the variable name without fully qualifiying it while within the block:

    use strict; use warnings; $main::var = 1; { our $var = 2; print $var, "\n"; # prints 2 } print $var, "\n"; # also prints 2

    Typical usage "at the top" applies to the whole file:

    use strict; use warnings; our $var = 1; { $var = 2; print $var, "\n"; # prints 2 } print $var, "\n"; # also prints 2

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://482218]
Approved by Nevtlathiel
Front-paged by kwaping
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (8)
As of 2014-10-23 09:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (125 votes), past polls