I recently discovered what seems to be an undocumented variable in Perl,
print keys %_;
Punctuation variables are exempt from strict. That's why you don't have to use something like
our $_; before using
$_. From perlvar,
Perl identifiers that begin with digits, control characters, or punctuation characters [...] are also exempt from
%_ isn't undocumented. From perlvar,
Perl variable names may also be a sequence of digits or a single punctuation or control character (with the literal control character form deprecated). These names are all reserved for special uses by Perl
You can have a hash named
_ is a valid name for a variable. (I'm sure you are familiar with
No Perl builtin currently sets it or reads
%_ implicitly, but punctuation variables such as
%_ are reserved.
Note that punctuation variables are also special in that they are "super globals". This means that unqualified
%_ refers to
%_ in the root package, not
%_ in the current package.
$ perl -E' %::x = ( "%::x" => 1 ); %::_ = ( "%::_" => 1 ); %Foo::x = ( "%Foo::x" => 1 ); %Foo::_ = ( "%Foo::_" => 1 ); package Foo; say "%x = ", keys(%x); say "%_ = ", keys(%_); say "%::x = ", keys(%::x); say "%::_ = ", keys(%::_); say "%Foo::x = ", keys(%Foo::x); say "%Foo::_ = ", keys(%Foo::_); ' %x = %Foo::x %_ = %::_ <-- surprise! %::x = %::x %::_ = %::_ %Foo::x = %Foo::x %Foo::_ = %Foo::_
This means that forgetting to use
local %_ (as you did) can have very far-reaching effects.