What is the significance of an underscore in Perl ($_, @_)?

This question always comes up, because it's Perl auto-magic (I made up that term).

foreach (@array_list){
  print $_ . "\n";
}

Is equivalent to:

foreach my $item (@array_list){
  print $item . "\n";
}

The difference is that when no variable is supplied for the loop, Perl automatically sets the default $_ to provide each item.

Similarly when calling subroutines (or methods - {subroutine in an object}) Perl puts the arguments to the subroutine in the @_ array, since arguments will always be a list.

On the flip side, when a built-in subroutine (or any well-written subroutine) requires arguments and is called with no arguments, it will usually function on $_ or @_ depending on if it's expecting one or many arguments. Some subroutines/methods (AKA functions) may work on either scalar or list values, and they usually default to scalar context and function on $_ by default. Sometimes the name makes it clear that it expects a list (array or hash) and then it defaults to @_ as its input.

Keep in mind, the flip side is talking about subroutine inputs, and their output depends on additional factors. In fact, subroutine outputs usually set $_ or @_ simply by returning a scalar value or list values.

For more on how to write a subroutine that returns values based on context check out wantarray and here's a good breakdown of it:

Advanced Subroutine Techniques


Those are special variables in Perl. Refer to Perl - Special Variables.


This is the sort of question which indicates you really should be reading a book, and perhaps the rest of the Perl tag FAQs.

Nevertheless, $_ is a context variable which is created implicitly by certain constructs and used implicitly by certain built-in functions. Here are some examples:

while(<>) {
    next if /^#/;
    last if /^q(?:uit)?$/;
    say "Howdy!" if /^hello$/;
}

This doing a lot of work setting and inspecting the $_ variable and is equivalent to:

while(defined($_ = <>)) {
    next if $_ =~ /^#/;
    last if $_ =~ /^q(?:uit)?$/;
    say "Howdy!" if $_ =~ /^hello$/;
}

Other constructs which set $_ are: foreach loops, given blocks, map and grep operations, and catch blocks in Try::Tiny.

Other constructs which use $_ are: bare print; statements, the s/// substitution operator and the tr/// transliteration operator.

I'd advise this: while you are learning Perl, don't use $_ implicitly. Write it all out in full (as in the second example above), to reinforce in your mind what is actually going on. Just like when you are learning a foreign language, you should learn to speak properly and carefully before you learn to abbrv y'language.

$_ is useful for writing shorter, terser code, and can actually be clearer by focussing on the processing going on rather than the variables it is being done to, but only once you have learned as second nature which operations are using $_. Otherwise it's just a confusing mess.

As mentioned elsewhere, @_ is the argument list to a subroutine.

Tags:

Perl