Re: What is the scope of $_?
by Athanasius (Archbishop) on Nov 26, 2012 at 14:55 UTC
|
sub xyz()
{
foreach(4..5)
{
...
$_ is implicitly localised, as though written:
sub xyz()
{
foreach local $_ (4..5)
{
...
which explains the behaviour you’re seeing.
Update: From perlsyn#Foreach-Loops:
If the variable is preceded with the keyword my, then it is lexically scoped, and is therefore visible only within the loop. Otherwise, the variable is implicitly local to the loop and regains its former value upon exiting the loop. If the variable was previously declared with my, it uses that variable instead of the global one, but it's still localized to the loop. This implicit localization occurs only in a foreach loop.
Hope that helps,
Athanasius <°(((>< contra mundum
| [reply] [d/l] [select] |
Re: What is the scope of $_?
by moritz (Cardinal) on Nov 26, 2012 at 16:10 UTC
|
To make things even more interesting, given creates a new lexical $_:
$ perl -wE '$_ = 1; sub p { say }; given (42) { say; p }'
42
1
| [reply] [d/l] |
|
| [reply] |
Re: What is the scope of $_?
by tobyink (Canon) on Nov 26, 2012 at 16:26 UTC
|
There is more than one $_. All your examples use the global $_. This is global in scope (as are all the "punctuation variables", except @_ which is just weird).
However, certain constructs implicitly localize variables. for loops do this.
Also (from Perl 5.10) you can create a new variable called $_ using my $_ or given (though the behaviour of given will change in 5.18 - it will not implicitly create a lexical $_). These have the same scope as any other lexical variables - the remainder of the block they're defined in, where the file itself counts as a block.
If you want to access your caller's lexical $_, then the official way is to use a sub prototype. I've also written lexical::underscore which allows you to delve multiple levels down the call stack.
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
| [reply] [d/l] [select] |
|
<tangent> How is @_ not global in scope? I mean, it gets implicitly localized on any subroutine call, but it's present by default and package independent:
use strict;
use warnings;
@_ = @ARGV;
package Foo;
print for @_;
@_ = qw(1 2 3 4 5);
{
local @_ = reverse @_;
print for @_;
}
package main;
print for @_;
</tangent>
#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.
| [reply] [d/l] [select] |
|
You are correct. I was under the impression that a reference to @_ behaved differently than a reference to another localized array, once the localization went out of scope.
But the following example appears to show they behave the same...
use strict;
use Data::Dumper;
our @X;
my ($underscore, $scissors);
@_ = (1..3);
@X = (1..3);
sub foo {
local @X = (4..6);
$underscore = \@_;
$scissors = \@X;
}
foo(4..6);
print Dumper($underscore, $scissors);
So (like $_) @_ is just a global array that gets localized by certain control structures. (In particular, sub.)
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
| [reply] [d/l] [select] |
|
use warnings;
use strict;
sub abc()
{
$_ = 'x';
}
foreach(1..2)
{
my $loopvar = 'in the loop';
print "Before:$_\n";
abc();
print "After:$_\n";
}
print "\$_ = $_\n"; # warning for uninitialized value $_ (global scop
+e)
abc();
print "\$_ = $_\n"; # prints $_ = x
| [reply] [d/l] [select] |
|
As I said, all the OP's examples use the global $_ but some Perl control structures localize that variable.
The same effect is illustrated here using global $::x...
use warnings;
use strict;
sub abc()
{
$::x = 'x';
}
foreach $::x (1..2)
{
print "Before:$::x\n";
abc();
print "After:$::x\n";
}
print "\$::x = $::x\n"; # warning for uninitialized value $x (global
+scope)
abc();
print "\$::x = $::x\n"; # prints $x = x
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
| [reply] [d/l] [select] |
|
Re: What is the scope of $_?
by Anonymous Monk on Nov 26, 2012 at 15:09 UTC
|
| [reply] |
Re: What is the scope of $_?
by Anonymous Monk on Nov 26, 2012 at 21:40 UTC
|
Dunno ... that's why I don't use it. All of these statements allow you to define your own my variable which will capture the necessary cursor-position within the body of the loop, thereby eliding the problem completely. There must be a reason for that... | [reply] |