Re: Scoping of my with foreach loop
by BrowserUk (Patriarch) on Mar 07, 2005 at 19:29 UTC
|
It doesn't make a lot of sense to use a loop variable that was previously declared, because the one that gets used within the loop is (temporarally), an entirely different variable, despite that it has the same name:
my $i = -23;
for $i ( 1 .. 10 ) {
print $i;
last if $i == 5;
}
print $i;
1
2
3
4
5
-23
Doing so tends to make look as if $i will retain the last value used in the loop, but as you can see, it doesn't.
It caught me out a couple of times and is something that I hope will not persist into Perl6.
In fact, I think I would change it in perl 5.10. Any code that got bitten by the change in behaviour would be better changed anyway.
Examine what is said, not who speaks.
Silence betokens consent.
Love the truth but pardon error.
| [reply] [d/l] |
Re: Scoping of my with foreach loop
by dragonchild (Archbishop) on Mar 07, 2005 at 19:08 UTC
|
Yes. In the second, $item is scoped only to the loop. In the first, $item is scoped outside the loop. You would use the second first if you want to access the value of $item outside the loop. As in
my $item;
foreach $item (@values) {
last if $item =~ /Some Complicated Regex/;
}
do_something_with( $item );
Update: Fixed typo as per Fletch's /msg.
Being right, does not endow the right to be rude; politeness costs nothing. Being unknowing, is not the same as being stupid. Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence. Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.
| [reply] [d/l] |
|
use strict;
my @values = (1, 2, 3, 'a', 4);
my $item = 'z';
foreach $item (@values) {
last if $item =~ /[^\d]/;
}
print($item); # Prints 'z', not 'a'.
I thought it might be using a localized global when my is omitted, but it's clearly not the case:
This is perl, v5.6.1 built for MSWin32-x86-multi-thread
| [reply] [d/l] [select] |
Re: Scoping of my with foreach loop
by ikegami (Patriarch) on Mar 07, 2005 at 19:24 UTC
|
use strict;
my @array = (1, 2, 3);
my $item = 'z';
foreach $item (@array) {}
print($item); # Prints 'z' (not '3'!!!).
use strict;
my @array = (1, 2, 3);
foreach my $item (@array) {}
print($item); # Compile error. $item only in scope for loop.
| [reply] [d/l] [select] |
Re: Scoping of my with foreach loop
by Fletch (Bishop) on Mar 07, 2005 at 19:09 UTC
|
Missing $ sigils aside: In the first example $item is visible outside and after the for BLOCK; in the second $item is only visible within the for BLOCK.
| [reply] [d/l] [select] |
Re: Scoping of my with foreach loop
by mikeB (Friar) on Mar 07, 2005 at 19:12 UTC
|
Neither will compile?
No, wait. That's a similarity. :)
Assuming you meant $item in each case, the difference would be in the scope of $item. In the second case it would be limited to the foreach block. | [reply] |
Re: Scoping of my with foreach loop
by Popcorn Dave (Abbot) on Mar 07, 2005 at 19:17 UTC
|
Other than it won't compile? You need to make that $item.
And yes you could concievably run in to scoping issues. Someone else will correct me if I'm incorrect about this but I believe that if for example, you declare my $item at the top of your program, then it's got global scope. However if that foreach loop was placed in a subroutine then it's going to be local to that routine and you wouldn't have access to it outside the loop.
If both of those are at the top of a script, then there shoudln't be any difference.
Update:Fletch picked up what I failed to take in to account completely about being visible within the foreach loop.
Useless trivia: In the 2004 Las Vegas phone book there are approximately 28 pages of ads for massage, but almost 200 for lawyers.
| [reply] |
Re: Scoping of my with foreach loop
by cog (Parson) on Mar 07, 2005 at 19:50 UTC
|
| [reply] |
|
use Benchmark;
my @array = (1..999999);
timethis (200, sub { my $foo; for $foo ( @array ) { 1; } });
timethis (200, sub { for my $foo ( @array ) { 1; } });
#timethis 200: 33 wallclock secs (31.58 usr + 0.02 sys = 31.60 CPU) @
+ 6.33/s (n=200)
#timethis 200: 32 wallclock secs (31.65 usr + 0.04 sys = 31.69 CPU) @
+ 6.31/s (n=200)
seems to be optimized (perl 5.8.6)
| [reply] [d/l] |