warnings::unused versus PPI

I had the following in my .bash_aliases file:

alias unused='perlcritic --single-policy ProhibitUnusedVariables'

However, I found a few cases where it didn't work. That's when mithaldu told me about warnings::unused. I installed it locally and ran it on some code which had a case that ProhibitUnusedVariables didn't find:

$ unused $some_module
$some_module source OK
$ perl -Mwarnings::unused -c $some_module 2>&1 | wc -l
34

Whoa! The one area were Perl::Critic modules repeatedly break for me is when I'm dealing with scope issues. It appears to miss where a variable is legitimately declared and used in one sub, but declared and unused in another. It also missed something like the following:

while ( my ($k,$v) = each %hash ) {
    my $k = munge($v);
}

And lucky me! The output of warnings::unused fits the format I'm expecting with the VI::Quickfix code I posted, so I just type :cf and :cn to jump to the next unused variable. Bonus: go ahead and delete them: vim's quickfix mode will note the deleted lines and still jump to the correct line.

Try dropping this in your .vimrc:

au! FileType perl :noremap <leader>c 
    \ :!time perl -Mwarnings::unused -MVi::QuickFix -c %<cr>

With that, every time you hit your leader and 'c', you'll get a quick compile check and a dump of all unused variables. Just hit ':cn" to keep jumping to the next one (or the next error, if you have any).

(Now if I can find some nifty code which finds variables declared outside of the scope they're needed ...)

10 Comments

Can perlcritic not find those cases and should an issue be raised for it?

Could you explain why warnings::unused doesn't work for this script

use warnings;
my $foo;
$ perl -Mwarnings::unused -c foo.pl
foo.pl syntax OK

but does for this script

use warnings;
{ my $foo; }
$ perl -Mwarnings::unused -c foo.pl
Unused variable my $foo at foo.pl line 2.
foo.pl syntax OK

and this one liner

$ perl -Mwarnings::unused -e 'use warnings; my $foo'
Unused variable my $foo at -e line 1.

?

Could you explain why warnings::unused doesn't work for this script

use warnings; my $foo;

$ perl -Mwarnings::unused -c foo.pl foo.pl syntax OK

but does for this script

use warnings; { my $foo; }

$ perl -Mwarnings::unused -c foo.pl Unused variable my $foo at foo.pl line 2. foo.pl syntax OK

and this one liner

$ perl -Mwarnings::unused -e 'use warnings; my $foo' Unused variable my $foo at -e line 1.

?

Ovid: I wasn't pointing the finger. I was wondering if that was something it should catch so a bug could be filed against it. I hope you took it in the best way.

Possible typo? Third paragraph, you refer to "warnings::register" rather than "warnings::unused"...

Leave a comment

About Ovid

user-pic Have Perl; Will Travel. Freelance Perl/Testing/Agile consultant. Photo by http://www.circle23.com/. Warning: that site is not safe for work. The photographer is a good friend of mine, though, and it's appropriate to credit his work.