I would say it's:
a violation of best practices on your part (always use as-local-as possible variable scope and avoid using $_
due to just the issue your encountered)
coupled with a bug in the API caused by the same violation of the best practices as well as not localizing the special variable with local $_
as proscribed by perldoc perlvar.
In addition to perldoc, the API violates Perl Best Practices (as in Conway's book's rules):
Section 5.6. Localizing Punctuation Variables
If you're forced to modify a punctuation variable, localize it.
The problems described earlier under "Localization can also crop up whenever you're forced to change the value in a punctuation variable (often in I/O operations). All punctuation variables are global in scope. They provide explicit control over what would be completely implicit behaviours in most other languages: output buffering, input line numbering, input and output line endings, array indexing, et cetera.
It's usually a grave error to change a punctuation variable without first localizing it. Unlocalized assignments can potentially change the behaviour of code in entirely unrelated parts of your system, even in modules you did not write yourself but are merely using.
Using local is the cleanest and most robust way to temporarily change the value of a global variable. It should always be applied in the smallest possible scope, so as to minimize the effects of any "ambient behaviour" the variable might control:
Here's full perldoc perlvar documentation as well - search for the word "nasty_break" in the web page (I couldn't find direct in-page link but it's close to the start of the page)
You should be very careful when
modifying the default values of most
special variables described in this
document. In most cases you want to
localize these variables before
changing them, since if you don't, the
change may affect other modules which
rely on the default values of the
special variables that you have
changed. This is one of the correct
ways to read the whole file at once:
- open my $fh, "<", "foo" or die $!;
- local $/; # enable localized slurp mode
- my $content = ;
- close $fh;
But the following code is quite bad:
- open my $fh, "<", "foo" or die $!;
- undef $/; # enable slurp mode
- my $content = ;
- close $fh;
since some other module, may want to
read data from some file in the
default "line mode", so if the code we
have just presented has been executed,
the global value of $/ is now changed
for any other code running inside the
same Perl interpreter.
Usually when a variable is localized
you want to make sure that this change
affects the shortest scope possible.
So unless you are already inside some
short {} block, you should create one
yourself. For example:
- my $content = '';
- open my $fh, "<", "foo" or die $!;
- {
- local $/;
- $content = ;
- }
- close $fh;
Here is an example of how your own
code can go broken:
- for (1..5){
- nasty_break();
- print "$_ ";
- }
- sub nasty_break {
- $_ = 5;
- # do something with $_
- }
You probably expect this code to
print:
- 1 2 3 4 5
but instead you get:
- 5 5 5 5 5
Why? Because nasty_break() modifies $_
without localizing it first. The fix
is to add local():
- local $_ = 5;