Reputation: 14949
Before writing this program,I thought that our
is a package scope variable and my
is
a file scope variable.But,After did that program,I am get confused.
My program is,
#!/usr/bin/perl
use strict;
use warnings;
package one;
our $val = "sat";
my $new = "hello";
print "ONE:val =>$val \n";
print "ONE:new =>$new \n\n";
package two;
print "TWO:val =>$val \n";
print "TWO:new =>$new \n";
which outputs
ONE:val =>sat
ONE:new =>hello
TWO:val =>sat
TWO:new =>hello
So,what is the difference between my
and our
.Whether the both are the same or it having any difference?
Upvotes: 13
Views: 3340
Reputation: 72636
my restrict the variables access to the innermost block in which they were declared. If there is no block, they are file-scoped.
our instead associates a simple name with a package variable in the current package , so it is declared at the package level and linked to the package name. our tries to help out by letting you use package variables without adding the package name.
package pack;
our $variable; # These are the same
$pack::variable; # These are the same
An our variable is something similar to C's static variable, but is different because the variable declared with our in a function is still accessible outside the function if it is called with the variable's fully qualified name.
But most of all my is lexically scoped while our is lexical scope but their life persistent even outside the declaring block(their life is like global variable life), therefore to really understand the difference between my and our you have to understand the difference between lexically and global scoped in Perl.
So briefly the difference between the two type are :
Any code, anywhere, can change their values.
The life of the variable end with the the end of the code block in with they are included, after that their values are garbage collected. These kind of variables can be accessed only within the block in which they are declared.
To answer you specific example-question : try to move the second package declaration (package two) into another file, and you will see the difference between my and our ...
Upvotes: 6
Reputation: 126722
It is important to distinguish between visibility and lifetime.
The visibility of variables declared using our
or my
is identical. You can used the name anywhere after the declaration before the first enclosing brace or end of file.
Beware that this doesn't apply to full-qualified variable names, which need no declaration and can be accessed anywhere. Without declaring anything I can assign to a package variable
$pack::three = 3;
and use that anywhere else in any package. I don't even have to declare the pack
package. But if I write
package pack;
our $three;
I have generated an shortened alias for $pack::three
that I can use within the same lexical scope as I could a my
variable in the same place: before an enclosing brace or end of file.
These package variables are always available from the start of the program's execution. Just like hash elements you can always assign to a new one and it will always be there - their lifetime is endless. In fact package variables are hash elements to all intents and purposes.
Lexical variables, declared with my
, on the other hand, are created at the point of declaration and destroyed once they go out of scope and there is no reference to them held anywhere. So, unless you take the reference of such a variable, its lifetime is the same as its visibility. A my
declaration inside a loop causes a new variable to be created and destroyed for each execution the loop.
In your code, you have created an alias $val
for package variable $one::val
and a lexical variable $new
. Neither are within a code block so both are visible to the end of the file. The package two
has no effect at all here, but if you had written our $val
after that second package statement you would have changed the alias $val
to indicate $two::val
instead.
I hope that helps.
Upvotes: 3
Reputation: 80384
As you see, both my
and our
have lexical effect.
my
creates a lexically scoped variable.
our
creates a lexically scoped alias to a package variable.
Just because you say package
in no fashion changes the lexical scope, so your $val
is still an alias to $one::val
even after having seen the package two
statement.
If you don’t see a close curly, you haven’t finished your scope. (Or EOF or end of string in a string eval
).
Upvotes: 20