tags:

views:

120

answers:

3

Hello! I've found in a Module a for-loop written like this

for( @array ) {
    my $scalar = $_;
    ...
    ...
}

Is there Difference between this and the following way of writing a for-loop?

for my $scalar ( @array ) {
    ...
    ...
}
+2  A: 

hi, I can't explain better than the doc can

ghostdog74
+11  A: 

Yes, in the first example, the for loop is acting as a topicalizer (setting $_ which is the default argument to many Perl functions) over the elements in the array. This has the side effect of masking the value $_ had outside the for loop. $_ has dynamic scope, and will be visible in any functions called from within the for loop. You should primarily use this version of the for loop when you plan on using $_ for its special features.

Also, in the first example, $scalar is a copy of the value in the array, whereas in the second example, $scalar is an alias to the value in the array. This matters if you plan on setting the array's value inside the loop. Or, as daotoad helpfully points out, the first form is useful when you need a copy of the array element to work on, such as with destructive function calls (chomp, s///, tr/// ...).

And finally, the first example will be marginally slower.

Eric Strom
Good answer, ++. However, I disagree that `for (@array) {}` should only be used if you will be operating primarily on `$_`. The fact that the first version forces a copy is beneficial if you plan on changing the `$scalar`'s value. There is no reason to write `for my $alias (@array) { my $scalar = $alias; ... }`. This in a particularly valid use of the topicalizer form of the for loop.
daotoad
@daotoad => I agree, answer updated, thanks for catching that
Eric Strom
+3  A: 

$_ is the "default input and pattern matching space". In other words, if you read in from a file handle at the top of a while loop, or run a foreach loop and don't name a loop variable, $_ is set up for you.

However, if you write a foreach loop and name a loop variable, $_ is not set up.This can be justified by following code:

1. #!/usr/bin/perl -w
2. @array = (1,2,3);
3. foreach my $elmnt (@array)
4. {
5.  print "$_ "; 
6. }

The output being "Use of uninitialized value in concatenation (.)"

However if you replace line 3 by:

foreach (@array)  

The output is "1 2 3" as expected.

Now in your case, it is always better to name a loop variable in a foreach loop to make the code more readable(perl is already cursed much for being less readable), this way there will also be no need of explicit assignment to the $_ variable and resulting scoping issues.

Neeraj