Member Rara Avis
The main difference between "my" and "local" are where and how Perl stores them in memory (the name space). I could probably spend three or four pages talking about "my" and "local" - or I can just give you a bit of history. When Perl first came out, "local" was the only alternative there was to global. It didn't work very well. So, the "my" scoping was added. And there's really little reason to use anything else.
The main reason for limiting the scope of a variable is to make sure it doesn't affect other parts of the program. One of the most common bugs is to add a new routine to a 5,000 line application and accidentally use a variable name that's already been used somewhere else. When your new routine changes the value of that variable, it make other parts of the app do some very weird things. Rule of thumb - global variables, that can accessed anywhere in the program, should be avoided like HIV.
When I started programming, computers had a lot less memory than is now typical, and we learned not to waste it unnecessarily. So, I tend to also use the "my" scoping to limit the lifetime of a variable. In the example you cite above, the @newIndex array can potentially get pretty big. But I know when the program execution leaves that elsif block, all the memory used by @newIndex will be released.
One caveat, though, if only because I see it in a lot of programs. The scope of a "my" variable is determined by the block where it was declared. Loops are blocks, too, but that is NOT where you want to put your declarations, not even for throw-away variables. For example, in the example above, we could have declared my ($mEmail, $key) = … without any change in the logic. Those variables aren't used outside the loop, they're just throw-away variables. But every time the loop ends and starts anew, Perl is going to clean them out of memory, only to set aside memory again the next time it hits the "my" statement. If that loop runs through a few thousand iterations, that can amount to a LOT of unnecessary overhead. Variable declarations should very rarely be made within loops.
You are correct, BTW, that push adds a value to an array. In the foreach loop, we check to see if the next $line in @index contains the email address you want to remove. If it doesn't, then we push it onto the @newIndex array. But if it IS the address we want to remove, we don't push it onto the new array. At the end of the loop, @newIndex should hold every $line that was in @index - EXCEPT for the email address you wanted to remove. We've essentially moved every element except one out of the original array into a new array. You wouldn't want to do something like this with a half-gigabyte file, but with arrays of just a few thousand small items, rebuilding it in memory is both the fastest and easiest to implement.