What is the difference between my and local in Perl?
Asked Answered
M

16

76

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?

Moonlit answered 24/9, 2008 at 20:12 Comment(0)
S
47

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
Shaitan answered 24/9, 2008 at 20:24 Comment(2)
You didn't call the subroutines.Aldora
Don't conditionally declare lexical variables: it has undefined behavior.Portage
C
68

The short answer is that my marks a variable as private in a lexical scope, and local marks a variable as private in a dynamic scope.

It's easier to understand my, since that creates a local variable in the usual sense. There is a new variable created and it's accessible only within the enclosing lexical block, which is usually marked by curly braces. There are some exceptions to the curly-brace rule, such as:

foreach my $x (@foo) { print "$x\n"; }

But that's just Perl doing what you mean. Normally you have something like this:

sub Foo {
   my $x = shift;

   print "$x\n";
}

In that case, $x is private to the subroutine and its scope is enclosed by the curly braces. The thing to note, and this is the contrast to local, is that the scope of a my variable is defined with respect to your code as it is written in the file. It's a compile-time phenomenon.

To understand local, you need to think in terms of the calling stack of your program as it is running. When a variable is local, it is redefined from the point at which the local statement executes for everything below that on the stack, until you return back up the stack to the caller of the block containing the local.

This can be confusing at first, so consider the following example.

sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }

$x = 1;
foo(); # prints '1'
bar(); # prints '2' because $x was localed in bar
foo(); # prints '1' again because local from foo is no longer in effect

When foo is called the first time, it sees the global value of $x which is 1. When bar is called and local $x runs, that redefines the global $x on the stack. Now when foo is called from bar, it sees the new value of 2 for $x. So far that isn't very special, because the same thing would have happened without the call to local. The magic is that when bar returns we exit the dynamic scope created by local $x and the previous global $x comes back into scope. So for the final call of foo, $x is 1.

You will almost always want to use my, since that gives you the local variable you're looking for. Once in a blue moon, local is really handy to do cool things.

Cuckoopint answered 24/9, 2008 at 20:26 Comment(0)
S
47

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
Shaitan answered 24/9, 2008 at 20:24 Comment(2)
You didn't call the subroutines.Aldora
Don't conditionally declare lexical variables: it has undefined behavior.Portage
B
30

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.

Bludgeon answered 24/9, 2008 at 22:58 Comment(0)
C
18

I can’t believe no one has linked to Mark Jason Dominus’ exhaustive treatises on the matter:

Ciliolate answered 25/9, 2008 at 23:25 Comment(2)
Word of warning: both of these articles are quite old, and the second one (by the author's own warning) is obsolete. It demonstrates techniques for localization of file handles that have been superseded by lexical file handles in modern versions of Perl.Castara
As in Clinton was President (of the US) when the first was writtenFernyak
T
10

http://perldoc.perl.org/perlsub.html#Private-Variables-via-my()

Unlike dynamic variables created by the local operator, lexical variables declared with my are totally hidden from the outside world, including any called subroutines. This is true if it's the same subroutine called from itself or elsewhere--every call gets its own copy.

http://perldoc.perl.org/perlsub.html#Temporary-Values-via-local()

A local modifies its listed variables to be "local" to the enclosing block, eval, or do FILE --and to any subroutine called from within that block. A local just gives temporary values to global (meaning package) variables. It does not create a local variable. This is known as dynamic scoping. Lexical scoping is done with my, which works more like C's auto declarations.

I don't think this is at all unclear, other than to say that by "local to the enclosing block", what it means is that the original value is restored when the block is exited.

Taxicab answered 24/9, 2008 at 20:21 Comment(0)
J
8

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.

Jankell answered 24/9, 2008 at 20:14 Comment(3)
While this may be true, it's basically a side effect of the fact that "local"s are intended to be visible down the callstack, while "my"s are not. And while overriding the value of a global may be the main reason for using "local", there's no reason you can't use "local" to define a new variable.Hindquarter
local does not actually define a new variable. For example, try using local to define a variable when option explicit is enabled. You need to use "our" or "my" to define a new global or local variable. "local" is correctly used to give a variable a new valueThermionics
Jesus did I really say option explicit to refer to the Perl feature. I meant obviously "use strict". I've obviously not coded in Perl in a whileThermionics
F
7

From man perlsub:

Unlike dynamic variables created by the local operator, lexical variables declared with my are totally hidden from the outside world, including any called subroutines.

So, oversimplifying, my makes your variable visible only where it's declared. local makes it visible down the call stack too. You will usually want to use my instead of local.

Freeliving answered 24/9, 2008 at 20:18 Comment(0)
S
5

Your confusion is understandable. Lexical scoping is fairly easy to understand but dynamic scoping is an unusual concept. The situation is made worse by the names my and local being somewhat inaccurate (or at least unintuitive) for historical reasons.

my declares a lexical variable -- one that is visible from the point of declaration until the end of the enclosing block (or file). It is completely independent from any other variables with the same name in the rest of the program. It is private to that block.

local, on the other hand, declares a temporary change to the value of a global variable. The change ends at the end of the enclosing scope, but the variable -- being global -- is visible anywhere in the program.

As a rule of thumb, use my to declare your own variables and local to control the impact of changes to Perl's built-in variables.

For a more thorough description see Mark Jason Dominus' article Coping with Scoping.

Sydelle answered 25/9, 2008 at 2:0 Comment(0)
P
5

local is an older method of localization, from the times when Perl had only dynamic scoping. Lexical scoping is much more natural for the programmer and much safer in many situations. my variables belong to the scope (block, package, or file) in which they are declared.

local variables instead actually belong to a global namespace. If you refer to a variable $x with local, you are actually referring to $main::x, which is a global variable. Contrary to what it's name implies, all local does is push a new value onto a stack of values for $main::x until the end of this block, at which time the old value will be restored. That's a useful feature in and of itself, but it's not a good way to have local variables for a host of reasons (think what happens when you have threads! and think what happens when you call a routine that genuinely wants to use a global that you have localized!). However, it was the only way to have variables that looked like local variables back in the bad old days before Perl 5. We're still stuck with it.

Penoyer answered 25/9, 2008 at 18:52 Comment(0)
C
3

"my" variables are visible in the current code block only. "local" variables are also visible where ever they were visible before. For example, if you say "my $x;" and call a sub-function, it cannot see that variable $x. But if you say "local $/;" (to null out the value of the record separator) then you change the way reading from files works in any functions you call.

In practice, you almost always want "my", not "local".

Curkell answered 24/9, 2008 at 20:18 Comment(0)
P
2

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
Plataea answered 10/4, 2013 at 5:44 Comment(0)
Z
1
&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.

Zohar answered 6/8, 2009 at 8:12 Comment(0)
P
1

It will differ only when you have a subroutine called within a subroutine, for example:

sub foo { 
    print "$x\n"; 
}
sub bar { my $x; $x = 2; foo(); }
    
bar(); 

It prints nothing as $x is limited by {} of bar and not visible to called subroutines, for example:

sub foo { print "$x\n"; }

sub bar { local $x; $x = 2; foo(); }
   
bar(); 

It will print 2 as local variables are visible to called subroutines.

Patricia answered 14/8, 2021 at 11:50 Comment(0)
M
0

dinomite's example of using local to redefine the record delimiter is the only time I have ran across in a lot of perl programming. I live in a niche perl environment [security programming], but it really is a rarely used scope in my experience.

Megaphone answered 1/10, 2008 at 16:1 Comment(0)
M
0

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.

Mercado answered 17/9, 2014 at 14:47 Comment(0)
O
0
#!/usr/bin/perl

sub foo { print ", x is $x\n"; }

sub testdefault { $x++; foo(); }        # prints 2

sub testmy { my $x; $x++; foo(); }       # prints 1

sub testlocal { local $x = 2; foo(); }    # prints 2. new set mandatory


print "Default, everything is global";
$x = 1;
testdefault();

print "My does not affect function calls outside";
$x = 1;
testmy();

print "local is everything after this but initializes a new";
$x = 1;
testlocal();

As mentioned in testlocal comment, declaring "local $x;" means that $x is now undef

Omniscient answered 10/11, 2022 at 7:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.