Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between my and local in Perl?

Tags:

scoping

perl

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?

like image 374
Brian G Avatar asked Sep 24 '08 20:09

Brian G


People also ask

What is the difference between my and our in Perl?

my is used for local variables, whereas our is used for global variables.

What is the use of my in Perl?

my keyword in Perl declares the listed variable to be local to the enclosing block in which it is defined. The purpose of my is to define static scoping. This can be used to use the same variable name multiple times but with different values.

What is difference between local and static object?

static object are initialized only once and live until the program terminates. Local object is created each time its declaration is encountered in the execution of program.

What is the difference between local and global object?

The main difference between Global and local variables is that global variables can be accessed globally in the entire program, whereas local variables can be accessed only within the function or block in which they are defined.


2 Answers

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.

like image 141
Jeremy Bourque Avatar answered Oct 03 '22 07:10

Jeremy Bourque


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 
like image 21
J.J. Avatar answered Oct 03 '22 05:10

J.J.