I am seeing both of them used in this script I am trying to debug and the literature is just not clear. Can someone demystify this for me?
Dynamic Scoping. It is a neat concept. Many people don't use it, or understand it.
Basically think of my
as creating and anchoring a variable to one block of {}, A.K.A. scope.
my $foo if (true); # $foo lives and dies within the if statement.
So a my
variable is what you are used to. whereas with dynamic scoping $var can be declared anywhere and used anywhere.
So with local
you basically suspend the use of that global variable, and use a "local value" to work with it. So local
creates a temporary scope for a temporary variable.
$var = 4;
print $var, "\n";
&hello;
print $var, "\n";
# subroutines
sub hello {
local $var = 10;
print $var, "\n";
&gogo; # calling subroutine gogo
print $var, "\n";
}
sub gogo {
$var ++;
}
This should print:
4
10
11
4
I think the easiest way to remember it is this way. MY creates a new variable. LOCAL temporarily changes the value of an existing variable.
Quoting from Learning Perl:
But local is misnamed, or at least misleadingly named. Our friend Chip Salzenberg says that if he ever gets a chance to go back in a time machine to 1986 and give Larry one piece of advice, he'd tell Larry to call local by the name "save" instead.[14] That's because local actually will save the given global variable's value away, so it will later automatically be restored to the global variable. (That's right: these so-called "local" variables are actually globals!) This save-and-restore mechanism is the same one we've already seen twice now, in the control variable of a foreach loop, and in the @_ array of subroutine parameters.
So, local
saves a global variable's current value and then set it to some form of empty value. You'll often see it used to slurp an entire file, rather than leading just a line:
my $file_content;
{
local $/;
open IN, "foo.txt";
$file_content = <IN>;
}
Calling local $/
sets the input record separator (the value that Perl stops reading a "line" at) to an empty value, causing the spaceship operator to read the entire file, so it never hits the input record separator.
Well Google really works for you on this one: http://www.perlmonks.org/?node_id=94007
From the link:
Quick summary: 'my' creates a new variable, 'local' temporarily amends the value of a variable.
ie, 'local' temporarily changes the value of the variable, but only within the scope it exists in.
Generally use my, it's faster and doesn't do anything kind of weird.
&s;
sub s()
{
local $s="5";
&b;
print $s;
}
sub b()
{
$s++;
}
The above script prints 6.
But if we change local to my it will print 5.
This is the difference. Simple.
Look at the following code and its output to understand the difference.
our $name = "Abhishek";
sub sub1
{
print "\nName = $name\n";
local $name = "Abhijeet";
&sub2;
&sub3;
}
sub sub2
{
print "\nName = $name\n";
}
sub sub3
{
my $name = "Abhinav";
print "\nName = $name\n";
}
&sub1;
Output is :
Name = Abhishek
Name = Abhijeet
Name = Abhinav