In Perl, can local () create a variable?

I read a lot of posts on Stackoverflow and on Google that say local does not create a variable, instead it works with existing ones.

I have a small snippet of code below, and I wonder how local works when there is no such variable already created.

 #use strict; #use warnings; &func; sub func{ local $temp = 20; print $temp; } 

I wrote this to understand the concept, and I'm relatively new to Perl.

+7
scope perl
source share
5 answers

If you do not declare a variable with my , variables without a full package specification will go into the current package. Here, as you can see the variables used for the first time and what they will be:

 my $temp; # a scoped, lexical variable that does not live in any package state $temp; # a persistent lexical variable our $temp; # a package variable in the current package, declared $temp; # a package variable in the current package $main::temp # a package variable in main $Foo::Bar::temp # a package variable in Foo::Bar local $temp # a package variable in the current package, with a dynamically-scoped (temporary) value 

local sets the scope of the package variable. When you declare this "dynamic" region, Perl uses the temporary value that you set to the end of the region. As with other package variables, Perl creates them when they are first used. The fact that you can use it first with local in front does not affect this.

Many people who tried to answer your question immediately lured you to strict . This is an auxiliary programming tool that helps you to enter the variable name by mistake, forcing you to declare all the variables that you are going to use. When you use a variable name that you have not declared, it stops compiling your program. You can do this with vars pragma, my , state or our :

 use vars qw($temp); our $temp; my $temp; state $temp; 

local not part of this, as you saw. What for? Because the way it is. I would like more if everything was different.

strict will not complain if you use the full package specification, for example $Foo::Bar::temp . You can fool all those who never notice.

I basically reserve the use of local for special Perl variables that you don't need to declare. If I want to use $_ in a routine, perhaps to use operators that use $_ by default, I will probably start with local $_ :

  sub something { local $_ = shift @_; s/.../.../; tr/.../.../; ...; } 

I probably most often use local with an input separator, so I can use different line endings without affecting, perhaps earlier:

  my $data = do { local $/; <FILE> }; 

They work because the first use of those variables that you have not seen is implied.

Otherwise, I probably want to make the variables private for my routine so that nothing outside the routine can see it. In this case, I do not need a package variable that the rest of the program can read or write. This job is for my variables:

 sub something { my $temp = ...; } 

A programming trick is a limitation of what can happen exactly with what you want. If the rest of your program cannot see or change the variable, my is the way to go.

I explain that this is Learning Perl and writing about the details of package variables in Perl Mastering .

+8
source share

local does not create a variable, but works on existing ones. but I have a small part of the code below, and I wonder how local works when there is no such variable already created .

Let's take a few steps and let perl do some diagnostics,

 perl -wE 'local $temp =3' Name "main::temp" used only once: possible typo at -e line 1. 

So local $temp modifies $main::temp , which is a package variable and

 perl -wE 'local $main::temp =3' Name "main::temp" used only once: possible typo at -e line 1. 

gives the same warning. So we created a new package variable that is localized.

What does it mean? This means that unlike our $temp it stores the value of the package variable ('global') $ temp until it exits the enclosing block , after which it restores the value to the previous value.

A few more tests,

 perl -MData::Dumper -E 'say Dumper [exists $main::{t}, ${$main::{t}}]' $VAR1 = [ '', # `$main::t` is NOT created in main package undef # retrieving value of `$main::t` thus returns undef ]; 

 perl -MData::Dumper -E '{our $t=7} say Dumper [exists $main::{t}, ${$main::{t}}]' $VAR1 = [ 1, # `$main::t` is created in main package 7 # value of `$main::t` ]; 

and finally

 perl -MData::Dumper -E '{local $t=7} say Dumper [exists $main::{t}, ${$main::{t}}]' $VAR1 = [ 1, # `$main::t` is *CREATED* in main package undef # value of `$main::t` reverts to undef at exit of enclosing block ]; 
+5
source share

local does not create a variable. Just mentioning $temp creates a variable. It is created when it is first encountered, whether at compile time or at run time.

 $ perl -E' $foo; ${"bar"}; BEGIN { say $::{foo} && *{ $::{foo} }{SCALAR} ? "exists" : "doesn'\''t exist"; } BEGIN { say $::{bar} && *{ $::{bar} }{SCALAR} ? "exists" : "doesn'\''t exist"; } BEGIN { say $::{baz} && *{ $::{baz} }{SCALAR} ? "exists" : "doesn'\''t exist"; } say $::{foo} && *{ $::{foo} }{SCALAR} ? "exists" : "doesn'\''t exist"; say $::{bar} && *{ $::{bar} }{SCALAR} ? "exists" : "doesn'\''t exist"; say $::{baz} && *{ $::{baz} }{SCALAR} ? "exists" : "doesn'\''t exist"; ' exists # $foo exists at compile-time doesn't exist # $bar doesn't exist at compile-time doesn't exist # $baz doesn't exist at compile-time exists # $foo exists at run-time exists # $bar exists at run-time doesn't exist # $baz doesn't exist at run-time 

Having variables created simply by naming them makes it difficult to detect typos. We use use strict; because he prevents it .

local only works at runtime. local temporarily reserves the value of $temp in a way that causes Perl to restore it when leaving the lexical domain.

 $ perl -E' sub f { say $temp; } $temp = 123; f(); { local $temp = 456; f(); } f(); ' 123 456 123 
+2
source share

You forgot to use use strict . If you do not use strict , the global variable of the $temp package will be used. See http://perlmaven.com/global-symbol-requires-explicit-package-name .

Package variables are always global. They have a package name and qualifier. You can omit the package qualifier, in which case Perl uses the default value that you can set with the package declaration. To avoid accidentally using global variables, add use strict 'vars' to your program. From the documentation :

use strict vars . This generates a compile-time error if you are accessing a variable that has not been explicitly declared (using any of my, ours, state or using vars) and does not have full qualifications. (Because this is to avoid variable suicide problems and subtle dynamic coverage problems, just a local variable is not good enough.)

0
source share

Without use strict - specifically use strict 'vars' , which is a subset - just mentioning the variable creates it in the current package. There is no need even for local , and your code can be written like this:

 sub func{ $temp = 20; print $temp; } func(); 

Exit

 20 

This is one of the reasons why use strict so important, and it is dangerous to omit it. Without this, you have no protection against spelling error variables and quiet hacking of your program

0
source share

All Articles