Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl magic -- Is foreach variable by default locally defined and override outer value

Tags:

perl

I am expecting @arr1's last element as output from this code:

#!/usr/bin/perl
my @arr1 = qw(son kon bon won kon don pon won pon don won);
my $innr_element = '';
foreach $innr_element ( @arr1 ) {
    ## do something
}
print "--->$innr_element<---\n";

But I am getting nothing (blank output). If $innr_element is being created internally by Perl as block-scoped variable (inner to foreach) then below should work properly.

#!/usr/bin/perl
use strict;
my @arr1 = qw(son kon bon won kon don pon won pon don won);
#my $innr_element = '';
foreach $innr_element ( @arr1 ) {
    ##do something
}
print "--->$innr_element<---\n";

But above code return below error.

Global symbol "$innr_element" requires explicit package name at test.pl line 5.
Global symbol "$innr_element" requires explicit package name at test.pl line 8.
Execution of test.pl aborted due to compilation errors.

So its clear that Perl is not creating inner variable implicitly.

This document says the same. If you declare VAR with my, the scope of the variable will extend throughout the foreach statement, but not beyond it.

Is this another perl magic or I am missing something?

like image 560
Gaurav Pant Avatar asked Dec 26 '22 21:12

Gaurav Pant


1 Answers

This is not described in much detail in the documentation, but here is what it says:

The foreach loop iterates over a normal list value and sets the variable VAR to be each element of the list in turn. 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.

So, it is not magic, the variable is merely localized. Your example might look something like this:

my $innr_element='';
foreach local $innr_element ( @arr1 ) {
...
like image 186
TLP Avatar answered Feb 19 '23 09:02

TLP