So we understand that use strict 'vars' ; will complain about the use of variables that have not been "declared" -- and very useful that is too. (Remembering that this doesn't apply to package variables referred to by their full name (the name including the package part).

In the case of my variables this is reasonably obvious and straightforward... my "declares" them.

You can use vars to "declare" package variables (eg  use vars qw($frob @mung %seen);), see vars -- but that is now "obsolete".

[For completeness: a package variable exists in the package symbol table, and can be accessed by its full name from any other package; a my variable can be accessed only where it is in lexical scope, and does not exist in the package symbol table. So, a package scalar $bar in the package ha::foo can be accessed from (say) main:: using its full name $ha::foo::bar. (Package variables are also known as global variables.) And, "lexical scope" means within the current BLOCK or file (if not in a BLOCK) -- noting the rules allow while (my $z = ...) to work as you'd assume it did</c>.]

So, our is roughly equivalent to my, except that it's for package variables. The tricky bit is the scope of an our declaration. our does two things: (a) it creates a package variable, which has global scope; (b) declares the variable's name, and that declaration has "lexical scope", in the same way as my.

The straightforward thing with packages is to: (a) have only one package per file and have that as the first statement in each file; and (b) use our declarations at the package level (not in any BLOCK). If you do that, then our does exactly what you'd expect.

You can place an our declaration inside a BLOCK, in which case the name is visible inside the block, and refers to the package variable. Use of the variable outside the scope of the our will trigger an error (under use strict 'vars'). To that extent the variable is "private". However: (a) it is still possible to access the variable using its full name; and (b) another our declaration elsewhere in the package will refer to the same variable. (If you were starting to think of our in terms of static, then stop right now.)

An our declaration outside any BLOCK has file scope. If you have more than one package in a file, then the name of an our variable in one package will be visible in the later packages in the file, and refers to the declaring package's package variable of that name.

These effects are illustrated in the code below, and I hope that the comments therein are sufficient to make things as clear as may be expected under the circumstances.

use strict ; use warnings ; my $lsub ; # visible in the packages that follow foo::z() ; # Initialise $foo::foo_global bar::z() ; # Initialise $bar::bar_global # Show that $foo_global is visible in package bar:: print "After $lsub: \$bar\::bar_global eq '$bar::bar_global'\n" ; # Show that $lsub was set by bar::z() # Show that $bar::bar_global is accessable by its full n +ame my $b = foo::b() ; # Initialise foo::b()'s our $fred & return subroutine to + access same print "After $lsub: &\$b() eq '", &$b(), "' eq \$foo\::fred eq '$foo:: +fred'\n" ; # Show that our $fred in foo::b() refers to $foo::fred # Show that $foo::fred is accessable by its full name my $a = foo::a() ; # Initialse foo::c()'s our $bill & return subroutine to +access same my $c = foo::c() ; # Initialse foo::c()'s our $bill & return subroutine to +access same foo::c() ; # Set foo::c()'s our $bill print "After $lsub: &\$a() eq '", &$a(), "' eq \$foo\::bill eq '$foo:: +bill'\n" ; # Show that foo::a()'s our $bill is the same as foo:c()' +s # ... which is $foo::bill foo::a() ; # Set foo::a()'s our $bill print "After $lsub: &\$c() eq '", &$c(), "' eq \$foo\::bill eq '$foo:: +bill'\n" ; # Show that foo::c()'s our $bill is the same as foo:a()' +s # ... which is $foo::bill package foo ; our $foo_global ; sub a { $lsub = 'foo::a()' ; our $bill = 'foo::a -- \$bill' ; return sub { $bill ; } ; } ; sub b { $lsub = 'foo::b()' ; our $fred = 'foo::b -- \$fred' ; ### my $q = $bill ; # Global symbol "$bill" requires explicit pack +age name... # Remove '###' to show $bill is "out of scope" under use + strict 'vars' return sub { $fred ; } ; } ; sub c { $lsub = 'foo::c()' ; our $bill = 'foo::c -- \$bill' ; my $q = $foo::fred ; # Show that we can access the global by its full name return sub { $bill ; } ; } ; sub z { $lsub = 'foo::z()' ; $foo_global = 'foo_global' ; } ; package bar ; our $bar_global ; sub z { $lsub = 'bar::z()' ; $bar_global = 'bar_global' ; print "$lsub: \$foo_global eq '$foo_global'\n" ; } ;

In reply to Re: the "our" declaration ?!! by gone2015
in thread the "our" declaration ?!! by perlpal

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.