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"...

About Ovid

user-pic Freelance Perl/Testing/Agile consultant and trainer. See http://www.allaroundtheworld.fr/ for our services. If you have a problem with Perl, we will solve it for you. And don't forget to buy my book! http://www.amazon.com/Beginning-Perl-Curtis-Poe/dp/1118013840/