Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the difference between "my" and "local" interact with symbolic references?

Tags:

perl

Previously I read related content in the book of "Effective Perl Programming", but didn't really understand it. Today, I encountered a problem about this, as below code.

my $vname = "a";
my @a = qw(1 2 3);
local @array = @$vname; 
foreach(@array) { print "$_\n"; };

It output nothing. Then I modified this line:

local @a = qw(1 2 3);  

Just replaced "my" with "local", then it works now. So I'd like to figure out what's the difference between them.

like image 772
thinkhy Avatar asked Nov 27 '22 04:11

thinkhy


2 Answers

There is a perldoc entry which answers this question in perlfaq7:

What's the difference between dynamic and lexical (static) scoping? Between local() and my()?

local($x) saves away the old value of the global variable $x and assigns a new value for the duration of the subroutine which is visible in other functions called from that subroutine. This is done at run-time, so is called dynamic scoping. local() always affects global variables, also called package variables or dynamic variables. my($x) creates a new variable that is only visible in the current subroutine. This is done at compile-time, so it is called lexical or static scoping. my() always affects private variables, also called lexical variables or (improperly) static(ly scoped) variables.

For instance:

sub visible {
    print "var has value $var\n";
}

sub dynamic {
    local $var = 'local';   # new temporary value for the still-global
    visible();              #   variable called $var
}

sub lexical {
    my $var = 'private';    # new private variable, $var
    visible();              # (invisible outside of sub scope)
}

$var = 'global';
visible();              # prints global
dynamic();              # prints local
lexical();              # prints global

Notice how at no point does the value "private" get printed. That's because $var only has that value within the block of the lexical() function, and it is hidden from the called subroutine.

In summary, local() doesn't make what you think of as private, local variables. It gives a global variable a temporary value. my() is what you're looking for if you want private variables.

See Private Variables via my() in perlsub and Temporary Values via local() in perlsub for excruciating details.

like image 179
Zaid Avatar answered Dec 21 '22 12:12

Zaid


my creates a new variable. It can only be seen in the lexical scope in which it is declared.

local creates a temporary backup of a global variable that's restored on scope exit, but does not reduce its scope (it can still be seen globally). It does not create a new variable.

You always want to use my when possible, but local is a decent approximation when you have to deal with global variables (e.g. $_).

like image 29
ikegami Avatar answered Dec 21 '22 12:12

ikegami