Perl code can seem dense at first, but it's full of linguistic shortcuts. These allow experienced programmers to glance at code and understand its important implications. Context is one shortcut. Another is default variables--the programming equivalent of pronouns.
The default scalar variable (or topic variable), $_
, is most notable in its absence: many of Perl's builtin operations work on the contents of $_
in the absence of an explicit variable. You can still type $_
if it makes your code clearer to you, but it's often unnecessary.
Many of Perl's scalar operators (including chr
, ord
, lc
, length
, reverse
, and uc
) work on the default scalar variable if you do not provide an alternative. For example, the chomp
builtin removes any trailing newline sequence from its operandSee perldoc -f chomp
and $/
for more precise details of its behavior.:
$_
behaves the same way in Perl as the pronoun it does in English. Without an explicit variable, chomp
removes the trailing newline sequence from $_
. When you write "chomp;
", Perl will always chomp it. These two lines of code are equivalent:
say
and print
also operate on $_
in the absence of other arguments:
Perl's regular expression facilities (chp.regex) default to $_
to match, substitute, and transliterate:
Perl's looping directives (looping_directives) default to using $_
as the iteration variable, whether for
iterating over a list:
... or while
waiting for an expression to evaluate to false:
... or map
transforming a list:
... or grep
filtering a list:
Just as English gets confusing when you have too many pronouns and antecedents, so does Perl when you mix explicit and implicit uses of $_
. In general, there's only one $_
. If you use it in multiple places, one operator's $_
may override another's. For example, if one function uses $_
and you call it from another function which uses $_
, the callee may clobber the caller's value:
If calculate_value()
or any other function changed $_
, that change would persist through that iteration of the loop. Using a named lexical is safer and may be clearer:
Use $_
as you would the word "it" in formal writing: sparingly, in small and well-defined scopes.
Perl also provides two implicit array variables. Perl passes arguments to functions (functions) in an array named @_
. Array operations (arrays) inside functions use this array by default. These two snippets of code are equivalent:
Just as $_
corresponds to the pronoun it, @_
corresponds to the pronouns they and them. Unlike $_
, each function has a separate copy of @_
. The builtins shift
and pop
operate on @_
, if provided no explicit operands.
Outside of all functions, the default array variable @ARGV
contains the command-line arguments provided to the program. Perl's array operations (including shift
and pop
) operate on @ARGV
implicitly outside of functions. You cannot use @_
when you mean @ARGV
.
ARGV
has one special case. If you read from the null filehandle <>
, Perl will treat every element in @ARGV
as the name of a file to open for reading. (If @ARGV
is empty, Perl will read from standard input; see filehandle.) This implicit @ARGV
behavior is useful for writing short programs, such as a command-line filter which reverses its input:
Why scalar
? say
imposes list context on its operands. reverse
passes its context on to its operands, treating them as a list in list context and a concatenated string in scalar context. If the behavior of reverse
sounds confusing, your instincts are correct. Perl arguably should have separated "reverse a string" from "reverse a list".
If you run it with a list of files:
... the result will be one long stream of output. Without any arguments, you can provide your own standard input by piping in from another program or typing directly. That's a lot of flexibility in a small program--and you're only getting started.
Hey! The above document had some coding errors, which are explained below:
- Around line 3:
-
A non-empty Z<>
- Around line 12:
-
A non-empty Z<>
- Around line 32:
-
Deleting unknown formatting code N<>
- Around line 187:
-
A non-empty Z<>