My Favorite Warnings: shadow
Who knows what evil lurks in the hearts of men? The Shadow knows!
OK, Perl does not literally have a warning about a 1930's pulp fiction and radio serial character. But Perl 5.28 introduced shadow
as a new warning category for cases where a variable is redeclared in the same scope. Previously, such warnings were under misc
.
To tickle this it is sufficient to
$ perl -Mstrict -Mwarnings -Mdiagnostics -e 'my $x; my $x;'
If your Perl is at least 5.28.0, you get the diagnostic
"my" variable $x masks earlier declaration in same scope at -e line 1 (#1) (W shadow) A "my", "our" or "state" variable has been redeclared in the current scope or statement, effectively eliminating all access to the previous instance. This is almost always a typographical error. Note that the earlier variable will still exist until the end of the scope or until all closure references to it are destroyed.
Earlier Perls (back to 5.6 which is when warnings
was introduced) give a similar warning, but the category is misc
.
It is hard to come up with a reason why you would want to disable this warning. An extremely contrived example (do not try this at home!) would be something like
sub make_closures { my ( $x ) = @_; my $c1 = sub { $x * $_[0] }; my $x = $x * 2; return ( $c1, sub { $x * $_[0] } ); }
But it would be far simpler and clearer just to call the second variable something else. If you absolutely, positively have to disable this under a range of versions of Perl, the changing category for this warning means you have to jump through some hoops. Something like this should do the trick:
my $x; # or whatever no if "$]" >= 5.028, qw{ warnings shadow }; no if "$]" < 5.028, qw{ warnings misc }; my $x;
Note that this warning category only covers earlier declarations in the same scope. Using the same-named variable in nested scopes does not generate this diagnostic:
$ perl -Mstrict -Mwarnings -Mdiagnostics -e 'my $x; { my $x; }'
is silent.
This warning category also covers our
and state
variables, and lexical subroutines.
The weed of crime bears bitter fruit! Crime does not pay...The Shadow knows!
Previous entries in this series:
But it’s easy to see why you would might want to make it fatal without also making everything else in
misc
fatal – which admittedly didn’t occur to me either until I went looking for the discussion about this change.the name is shadow! I expected it is something like mask before hahaha
Point well taken. I honestly think words like 'occlude' or 'eclipse' are more descriptive, but I do not think they are current in the Perl community.