Sally Goldin
Sally Goldin

Reputation: 61

perl 'last' statement and variable scope

Should-be simple Perl construction is not behaving as I expect.

The @closest array holds strings of the form "NNN-NNN". I am trying to find the first array element where the initial "NNN" matches a specific value.

Since I have declared $compoundKey outside the loop, I expect it to be persistent. The loop behaves as expected, exiting when I get a match. However, after the code exits the loop, the $compoundKey variable is empty. (See log output after code. I am looking for "83". The matched element is not the last element in the array.)

    my $compoundKey;
    foreach $compoundKey (@closest)
    {
        logentry("In loop compoundKey is $compoundKey\n");
        last if ($compoundKey =~ /^$RID/);   
    }
    logentry("Outside loop compoundKey is $compoundKey\n");

Log file:

    2019-02-27 18:15:26: In loop compoundKey is 90-1287
    2019-02-27 18:15:26: In loop compoundKey is 86-1223
    2019-02-27 18:15:26: In loop compoundKey is 86-1235
    2019-02-27 18:15:26: In loop compoundKey is 87-1316
    2019-02-27 18:15:26: In loop compoundKey is 89-1219
    2019-02-27 18:15:26: In loop compoundKey is 83-1224
    2019-02-27 18:15:26: Outside loop compoundKey is 

I assume I can fix this by doing an explicit assignment of a temporary loop variable to $compoundKey, but I'm still somewhat mystified. Is there some bug in my code that I am not seeing? Or does the "last" statement in Perl behave in a totally different way than "break" in C or Java?

Thanks!

Upvotes: 3

Views: 685

Answers (1)

mob
mob

Reputation: 118605

It's not the last statement, it's the foreach statement.

The foreach loop iterates over a normal list value and sets the scalar 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. (Emphasis added).

Upvotes: 8

Related Questions