Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: the "our" declaration ?!!

by gone2015 (Deacon)
on Jan 20, 2009 at 11:49 UTC ( [id://737554]=note: print w/replies, xml ) Need Help??


in reply to the "our" declaration ?!!

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" ; } ;

Replies are listed 'Best First'.
Re^2: the "our" declaration ?!!
by perlpal (Scribe) on Jan 20, 2009 at 12:10 UTC
    Thank you for the detailed explanation , it helped in clearing a lot of my doubts.

Log In?
Username:
Password:

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

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

    No recent polls found