Re: difference between my and local
by davorg (Chancellor) on Nov 15, 2005 at 12:47 UTC
|
Perl has two different and completely unrelated systems for creating variables.
Package variables (also sometimes known as global variables) are what you get if you just start using a variable without declaring it first. You can also explicitly create package variables with "use vars" or "our".
Lexical variables are created when you use "my".
You should be using lexical variables unless you have a good reason not to.
This is explained well by Dominus in his article Coping with Scoping. He also has a follow-up article Seven Useful Uses of local where he describes seven cases where you might want to use package variables instead of lexical variables.
--
< http://dave.org.uk>
"The first rule of Perl club is you do not talk about
Perl club." -- Chip Salzenberg
| [reply] |
|
|
| [reply] |
Re: difference between my and local
by Perl Mouse (Chaplain) on Nov 15, 2005 at 12:56 UTC
|
my creates a new variable which is only valid inside a sub or block
Yes, to be more accurate: my creates a variable that exists till the end of the innermost enclosing block.
local uses the global var and saves its original value and you can give it a new value which is also only valid inside a sub or block
Yes, and the value exists till the innermost enclosing block is exited.
So..... both create a new variable.
How did you draw that conclusion? In your description of local you say it uses the global variable, and saves its original value, giving you a new value. That's correct - it uses the global variable.
The following is an easy reminder of the difference:
my creates a new variable; local creates a new value.
Note also that a myed variable isn't visible outside the block it's declared in, while a localized value is:
#!/usr/bin/perl
use strict;
use warnings;
use vars '$global';
my $lexical;
$global = 'outer';
$lexical = 'outer';
sub show {
printf "\$global is '%s'; \$lexical is '%s'\n", $global, $lexical;
}
show;
{
local $global = 'inner';
my $lexical = 'inner';
show;
}
__END__
$global is 'outer'; $lexical is 'outer'
$global is 'inner'; $lexical is 'outer'
| [reply] [d/l] |
|
|
Good examples, I've never used stict and warnings, but now those make more sense too.
Can someone give me an example in which the difference between our and my gets clear ?
Thanks a lot!!!!!!
Luca
ps I should have added our too to the title of this post
| [reply] |
|
|
$ perl -Mstrict -lne 'our $c += () = /foo/g; END { print $c }'
abc foo
foo foo
3
$ perl -Mstrict -lne 'my $c += () = /foo/g; END { print $c }'
abc foo
foo foo
1
Ok: always use strict. But not in one-liners...
So our is somewhat "exotic" in that it declares a package variable, but in a lexical scope.
Update: removed the statement modifiers that had inadvertently (yes!) slipped in as per Perl Mouse's remark | [reply] [d/l] |
|
|
|
|
|
|
Yes, to be more accurate: my creates a variable that exists till the end of the innermost enclosing block.
And to be even more accurate, it creates a variable that has a name that exists until the end of the block (or until the name is shadowed by a duplicated identical name). The variable itself might persist beyond the end of the block (as an anonymous variable), if there are still other references to the variable.
| [reply] |
Re: difference between my and local
by Limbic~Region (Chancellor) on Nov 15, 2005 at 13:38 UTC
|
jeanluca,
I am sure by now you have already had your question answered, but did you consider you had all the tools necessary to answer it yourself? In the Tutorials section, you would have found in addition to the "Coping with Scoping" link:
The PerlMonks site also has a Super Search feature which would have allowed you to search for others that have asked the same question to see what answers they received. This site also has a Categorized Questions and Answers section. The perldoc utility has a -q option for searching the FAQ section for keywords and there are several Perl FAQ web sites to search from.
You may perceive this to be an admonishment. The intent isn't to ridicule, it is to point out the vast resources available for solving your own problems.
| [reply] |
Re: difference between my and local
by dave_the_m (Monsignor) on Nov 15, 2005 at 12:48 UTC
|
my $my = 0;
$global = 0;
sub p { print "my = $my, global = $global\n" }
{
local $global = 1;
my $my = 1;
p();
}
__END__
$ perl /tmp/p
my = 0, global = 1
$
Dave. | [reply] [d/l] |
Re: difference between my and local
by jonix (Friar) on Nov 15, 2005 at 12:42 UTC
|
You will also see more difference when you use strict, as it will complain when you localize a global variable which is not yet initialized:
"Global symbol (...) requires explicit package name ...".
Cheers
jonix | [reply] |
|
|
I get: Can't localize lexical variable $var at ./a.pl line 11
What exactly does our do ?
Your example shows that you can only use local on global variables... So why use my anyway ?
Luca
| [reply] |
|
|
| [reply] |
|
|
| [reply] |
Re: difference between my and local
by blazar (Canon) on Nov 15, 2005 at 13:32 UTC
|
The difference between local and my is that somewhat surprisingly the former doesn't really declare local variables! Oh but much better than I ever could you will find detailed explanations in the following two articles:
Oh, and a little self-ad on a related topic: Re: Are we seeing syntax inconsistency?
| [reply] [d/l] [select] |
Re: difference between my and local
by Moron (Curate) on Nov 15, 2005 at 12:51 UTC
|
# main scope
$fred = 1; #global
#...
{ # outer scope
my $fred = 2;
#...
{ #inner scope
#...
}
}
In the outer scope, you could argue you don't need local because you can theoretically assign a localised $fred to the value of global $fred with just my $fred = $fred;. But in the inner scope, local provides the only means of access to global $fred (other than referencing it by package name) because otherwise access to global $fred is blocked by the presence of outer scope's $fred.
| [reply] [d/l] [select] |
|
|
I'm not quite sure what you're getting at, but you can certainly get the global value from anywhere, without using local. Observe:
# main scope
$fred = 1; #global
{ # outer scope
my $fred = 2;
#...
{ #inner scope
print $main::fred; # prints the global 1
}
}
The best rule of thumb is to use my unless you have some particular reason to use something else. | [reply] [d/l] [select] |
|
|
You'll find that my is used more often than local. So what I am getting at is that whereas my $fred = $fred will have the same effect as local $fred most of the time, it won't always. I expect the OP to wonder why he ever needs local instead of just using my $fred = $fred rather than to wonder why he needs my - he already knows why he needs my and he already knows broadly what both of these do.
| [reply] |
Re: difference between my and local
by Fletch (Bishop) on Nov 15, 2005 at 13:22 UTC
|
For some reason no one's mentioned mjd's Coping with Scoping yet . . .
Update: Gah, I see now davorg did. ENOCAFFEINE
| [reply] |
Re: difference between my and local
by jesuashok (Curate) on Nov 15, 2005 at 12:31 UTC
|
#!/usr/local/bin/perl
+
our $var = 10;
+
{
local $var = 5;
print "in var :$var:\n";
}
+
print "out var :$var:\n";
Please try the aboce code.
Then create a variable with my scope. try to localise the Variable You will find the difference.
"Keep pouring your ideas"
| [reply] [d/l] |
Re: difference between my and local
by radiantmatrix (Parson) on Nov 15, 2005 at 14:55 UTC
|
There are many, many excellent answers above, I suggest you read all of those links! (And thanks to those that posted them, I learned a bit more about the nuances.)
I'd like to share my very simplistic way of thinking about them, which helps me keep the two separated in my head. Basically, you use my when you want to create a variable that a specific scope owns; and you use local when you want to create a "local copy" of a variable for a specific scope.
A great example of when to use local is when working with the variables in perlvar. If you have a module named NiftyModule and you declare my $/ = "\n";, you create $NiftyModule:/. That's probably not what you wanted to happen. But, declaring local $/ = "\n" makes a local copy of the special $/, which is what you want.
| [reply] [d/l] [select] |
| A reply falls below the community's threshold of quality. You may see it by logging in. |