views:

156

answers:

2

From the "our" perldoc:

our has the same scoping rules as my, but does not necessarily create a variable.

This means that variables declared with our should not be visible across files, because file is the largest lexical scope. But this is not true. Why?

+13  A: 

You can consider our to create a lexically-scoped alias to a package global variable. Package globals are accessible from everywhere; that's what makes them global. But the name created by our is only visible within the lexical scope of the our declaration.

package A;
use strict;
{
  our $var; # $var is now a legal name for $A::var
  $var = 42; # LEGAL
}

say $var; # ILLEGAL: "global symbol $var requires explicit package name"
say $A::var; # LEGAL (always)

{
  our $var; # This is the same $var as before, back in scope
  $var *= 2; # LEGAL
  say $var; # 84
}
hobbs
Thanks, I understand now.
eugene y
It really is an alias, if it where just an exemption to `strict` then `perl -le 'our $foo = 42; package A; print "$foo $main::foo"'42 42` would print the same thing as `perl -le 'use vars qw/$foo/; $foo = 42; package A; print "$foo $main::foo"'`, which is an exemption, and we wouldn't need `our`.
Chas. Owens
@Chas good point.
hobbs
+7  A: 

You have a good answer already, but perhaps this will be helpful as well.

The our declaration combines aspects of my and use vars. It functions similarly to use vars in that it declares package variables; however, variables declared in this way are lexically scoped and cannot be accessed outside the scope in which they were declared (unless you use the fully qualified name of the variable). In addition, a variable declared with our is visible across its entire lexical scope, even across package boundaries.

Here's a table that I added to my Perl notes a while back. For an example, see this SO answer.

              Scope/     Package
              Namespace  Variable    Private    New
---------------------------------------------------
my            Lexical    No          Yes        Yes
our           Lexical    Yes         No         No
use vars      Package    Yes         No         No
FM
People have to remember that packages don't create a scope: [Know what creates a scope](http://www.effectiveperlprogramming.com/blog/48).
brian d foy
@brian I take your point, and the article you wrote is a good one, but I wonder whether packages have certain scope-like characteristics. For example: `perl -le 'package Foo; $x += 10; print $x; package B; $x += 10; print $x'`. Perhaps there a better word than "scope" to describe what's going on with that example? Thanks for the input.
FM
The better word is "default package". The package doesn't limit the visibility of the variables, though. It's not at all like a scope.
brian d foy
@brian I guess I would prefer to describe things less starkly. Packages do limit the visibility of variables -- but only to a limited degree. Inside `package Bar`, `$Foo::x` may not be invisible, but it is blurry. Or maybe one could say that it is cloaked behind a namespace, which is perhaps the alternative word I was looking for. And if we allow black magic, even lexically scoped variables are not entirely invisible outside their lexical domains. In any case, scoping and namespaces are not unrelated. If nothing else, they share some underlying motivations.
FM
Your thinking about it wrong. Packages do nothing to limit visibility. Saying anything else is just wrong.
brian d foy