Yokupoku Maioku
Yokupoku Maioku

Reputation: 503

Accessing variable outside foreach loop

what is the scope of a variable declared in this way:

foreach $variable (<FILE>){
    if($variable...){

    }
}
print "$variable \n";

is it possible to use it outside loop?

thanks in advance.

Upvotes: 3

Views: 1692

Answers (2)

Axeman
Axeman

Reputation: 29854

At first, it would seem that it should work, because you're obviously not running this code with strict as you don't declare $variable. And you're not declaring it a lexical variable (my $variable), so it is a "package variable", and works like a global.

However, Perl needlessly, localizes the scope of the loop variable.

And even though this looks like it should work:

use strict;
use warnings;
use feature 'say';
...
my $variable; # creates a lexical variable. 

foreach $variable (<FILE>){
    if($variable...){
        ...
    }
}
say $variable; # modern form of: print "$variable \n";

Perl needlessly again, localizes the scope of the variable.

Often you can declare the lexical as part of the loop. Like so:

foreach my $variable ( <FILE> ) { 
    ...
}

It does not allow you to access that variable outside of the loop. However, whether you specify my in the loop or not, just putting the variable before the parenthesis localizes the scope of whatever variable you might use.

So if you want to know what the value is outside the loop, it has to be explicitly other than the loop variable.

my $var;

foreach $variable ( <FILE> ) { 
    $var = $variable;
}  
say $var;

In the comments below, you asked me what better way to read a file. So the below contains some nitpicks.

  • By far the best way to loop through a file is a while loop. It has much less overhead than a foreach loop, and the Perl syntax makes it easy to use.

    use English qw<$OS_ERROR>; # imports a standard readable alias for $!
    
    # 1) Use lexical file handles, not "barewords"; 2) use 3-argument open; 
    # 3) always open or die. 
    open( my $handle, '<', 'foo.txt' ) 
        or die "Could not open file: $OS_ERROR!"
        ;
    while ( my $line = <$handle> ) {
        ... 
    }
    close $handle;
    

Upvotes: 6

mpapec
mpapec

Reputation: 50677

Yes, it is possible, but be aware that variable is always localized to the loop (restores previous value after the loop).

From perldoc perlsyn

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.

Upvotes: 3

Related Questions