perlperlvar

How is $_ different from named input or loop arguments?


As I use $_ a lot I want to understand its usage better. $_ is a global variable for implicit values as far as I understood and used it.

As $_ seems to be set anyway, are there reasons to use named loop variables over $_ besides readability?

In what cases does it matter $_ is a global variable?

So if I use

for (@array){
    print $_;
}

or even

print $_ for @array;

it has the same effect as

for my $var (@array){
    print $var;
}

But does it work the same? I guess it does not exactly but what are the actual differences?

Update:

It seems $_ is even scoped correctly in this example. Is it not global anymore? I am using 5.12.3.

#!/usr/bin/perl
use strict;
use warnings;

my @array = qw/one two three four/;
my @other_array = qw/1 2 3 4/;

for (@array){
    for (@other_array){
        print $_;
    }
    print $_;
}

that prints correctly 1234one1234two1234three1234four.

For global $_ I would have expected 1234 4 1234 4 1234 4 1234 4 .. or am i missing something obvious?

When is $_ global then?

Update:

Ok, after having read the various answers and perlsyn more carefully I came to a conclusion:

Besides readability it is better to avoid using $_ because implicit localisation of $_ must be known and taken account of otherwise one might encounter unexpected behaviour.

Thanks for clarification of that matter.


Solution

  • are there reasons to use named loop variables over $_ besides readability?
    

    The issue is not if they are named or not. The issue is if they are "package variables" or "lexical variables".

    See the very good description of the 2 systems of variables used in Perl "Coping with Scoping":

    http://perl.plover.com/FAQs/Namespaces.html

    package variables are global variables, and should therefore be avoided for all the usual reasons (eg. action at a distance).

    Avoiding package variables is a question of "correct operation" or "harder to inject bugs" rather than a question of "readability".

    In what cases does it matter $_ is a global variable?
    

    Everywhere.

    The better question is:

    In what cases is $_ local()ized for me?
    

    There are a few places where Perl will local()ize $_ for you, primarily foreach, grep and map. All other places require that you local()ize it yourself, therefore you will be injecting a potential bug when you inevitably forget to do so. :-)