I have read many posts in Stackoverflow and in Google which tell that local
does not create a variable, instead it works on the existing ones.
I have a small piece of code below and I wonder how local
is working when there is no such variable already created.
#use strict;
#use warnings;
&func;
sub func{
local $temp = 20;
print $temp;
}
This I wrote just to understand the concept and I am relatively new to Perl.
Unless you declare a variable with
my
, variables without a full package specification go into the current package. Here's how you might see variables used for the first time and what they would be:The
local
sets the scope of a package variable. When you declare this "dynamic" scope, Perl uses the temporary value you set until the end of the scope. As with other package variables, Perl creates them when you first use them. That you might use it first withlocal
in front doesn't affect that.Many people who tried to answer your question immediately nagged you about
strict
. This is a programming aid that helps you not mistype a variable name by forcing you to declare all variables you intend to use. When you use a variable name you haven't declared, it stops the compilation of your program. You can do that with thevars
pragma,my
,state
, orour
:local
isn't part of that, as you've seen. Why? Because that's just how it is. I'd like it more if it were different.strict
won't complain if you use the full package specification, such as$Foo::Bar::temp
. You can mistype all of those without ever noticing.I mostly reserve my use of
local
for Perl's special variables, which you don't have to declare. If I want to use$_
in a subroutine, perhaps to use the operators that use$_
by default, I'll probably start that withlocal $_
:I probably use
local
more often with the input record separator so I can use different line endings without affecting might have come before:Those work because there's an implicit first use of those variables that you haven't seen.
Otherwise, I probably want to make variables private to its subroutine so nothing outside the subroutine can see it. In that case, I don't want a package variable that the rest of the program can read or write. That's the job for
my
variables:The trick of programming is to limit what can happen to exactly what you want. If the rest of your program shouldn't be able to see or change the variable,
my
is the way to go.I explain this is Learning Perl and write about the details of the package variables in Mastering Perl.
Lets make a few steps, and let the perl do some diagnostics,
So
local $temp
alters$main::temp
which is package variable andgives the same warning. So we created a new package variable which is localized.
What does this mean? It means that unlike
our $temp
it keeps the value of package ('global') variable $temp until it exits enclosing block at which point it restores value to previous value.A few more tests,
and finally,
Without
use strict
-- specificallyuse strict 'vars'
, which is a subset -- just mentioning a variable creates it in the current package. There is no need even forlocal
, and your code can be written like thisoutput
That is one reason why
use strict
is so important, and it is dangerous to omit it. Without it you have no protection against misspelling variables and silently breaking your programlocal
does not create a variable. Simply mentioning$temp
is creating the variable. It is created when as soon as it is first encountered, whether at compile-time or at run-time.Having variables created simply by naming them makes it hard to spot typos. We use
use strict;
because it prevents that.local
only has a run-time effect.local
temporarily backs up the value of$temp
in a way that causes Perl to restore it when the lexical scope is exited.You forgot to use
use strict
. If you do notuse strict
the global package variable$temp
will be used.. See http://perlmaven.com/global-symbol-requires-explicit-package-name.Package variables are always global. They have a name and a package qualifier. You can omit the package qualifier, in which case Perl uses a default, which you can set with the package declaration. To avoid using global variables by accident, add
use strict 'vars'
to your program. From the documentation: