I am having few doubts for local/our
scope in perl. I read lot of documentation but still confusion is there. Following are the confusions
What is local
scope?
what I read is -> local copies the value of global variable, change the value, user will use it and outside the block it will retain the global value
Confusion -> my
does the same thing. Only benefit I see is that some variables like $package::var
cannot be declared with my scope but can be declared with local scope. What else for local
What is "global" variable?
What is read is -> Its scope is within the package. Basically we put the global variable in @EXPORT
array and use it or append the namespace with it to use in other packages.
doubt -> Again if we declare variable with my
scope in main only then we can access the variable throughout the package. Is that right? Is it possible to add the my
scoped variables in @EXPORT
array and use it in another packages?
I think global variables are declared with our
keyword. Is there any other way to do so?
This question may look like repetitive but i am confused
In terms of scoping, there are two kinds of variables in Perl.
- Lexical variables are lexically scoped, which means they are only visible in the current lexical scope.
- Package variables are globally scoped, which means they are visible by all code in the interpreter.
Here are ways to create variable.
my
creates a lexical variable.
our
creates a lexical variable that is aliased to the variable of the same name in the current package. In other words, our $foo;
is the same as alias my $foo = $The::Current::Package::foo;
.
- Global variables are created on use.
local
doesn't create any variables. It simply backs up a variable until the current lexical scope is destroyed.
my
does the same thing.
No. local
does not change the scope of a variable. While a lexical variable is only visible in a lexical scope, a localized global variable is still visible across the entire interpreter.
$x = 123;
sub foo { print "$x\n"; }
{ local $x = 456; foo(); } # 456
foo(); # 123
$x = 123;
sub foo { print "$x\n"; }
{ my $x = 456; foo(); } # 123
foo(); # 123
What else for local
local
is primarily used to approximate the functionality of my
for variables that cannot otherwise be declared lexically.
(Historically, that was all variables. Since 5.6, only punctuation variables cannot be declared lexically.)
What is "global" variable?
A variable that can seen globally, i.e. by any code in the interpreter.
Is it possible to add the my scoped variables in @EXPORT array and use it in another packages?
No. @EXPORT
is used by Exporter. Exporter would not be able to find anything but global symbols (since files are compiled in fresh lexical scopes), so @EXPORT
must only contain global symbols.
There are two kinds of variables, lexically scoped and globally scoped.
In Perl before version 5, there was only globally scoped. These variables are the package variables. These variables are available everywhere in the program if you use the package prefix.
The local
keyword was introduced to provide a way to alter the value of one of these package global variables inside a limited scope, such as inside one subroutine. It will save the old value on a stack when entering the scope with the local
statement, and upon exiting, it will restore the old value. These are still package globals, which means that they are still available everywhere. If you are inside a scope with a local
variable, and you call a subroutine, that variable is still visible inside that subroutine.
The my
keyword was introduced in version 5, and provides lexically scoped variables. These variables only exist inside the scope where they are declared. This means that if you call a subroutine, that my
variable is not visible. Upon exiting a scope, the my
variables simply go away. You should prefer to use my
variables when possible, because you do not want your variables to be visible inside subroutines that you call. You cannot use these type of variables in the @EXPORT
list because these variables are not visible outside of their scope.
Finally, the our
keyword is a combination of both, in that it gives you a variable that is a package global, but that variable is lexically scoped. This means it will be available anywhere in the program, but at the end of the enclosing block, you cannot refer to that variable any more.
Example 1:
sub mess_with_foo {
$foo=0;
}
sub myfunc {
my $foo=20;
mess_with_foo();
print $foo;
}
myfunc();
Example 2:
sub mess_with_foo {
$foo=0;
}
sub myfunc {
local $foo=20;
mess_with_foo();
print $foo;
}
myfunc();
Example 1 prints 20
because mess_with_foo()
could not see my $foo
. It could not change it. my $foo
can only be seen in its scope of myfunc()
.
Example 2 prints 0
because mess_with_foo()
can see my $foo
and change it. local $foo
can be seen in its scope of myfunc()
AND in the scope of any function called from within its scope of myfunc()
.
That's the only difference. Neither my $foo
nor local $foo
will be seen outside of their scope of myfunc()
.