Using vim to find unecessary modules in tests

Ovid on 2007-12-11T12:05:58

I see a number of tests like this:

use This;
use That;
use The::Other::Thing;
use Foo::Bar;

And when looking at all of those, I wonder which we're actually using. So I added this quick hack to my .vimrc:

map ,ut :call ConvertUseToTest()
function! ConvertUseToTest()
    s/use \(.\+\);/&\rok exists $INC{'\1.pm'}, '\1 exists in %INC';/
    s/::/\//g
    nohl
endfunction

Position your cursor on, say, the "use Foo::Bar;" line, type ",ut" ("use test") and you get this:

use This;
use That;
use The::Other::Thing;
use Foo::Bar;
ok exists $INC{'Foo/Bar.pm'}, 'Foo/Bar exists in %INC';

It's not perfect, but it's a good start. Now I run the test and verify that Foo::Bar has been loaded. I then delete the use Foo::Bar line and rerun the tests. Assuming all tests pass except the new test we've just added, then I know that it's safe to leave the use Foo::Bar line out of the code.

(If the "exists in %INC" test passes, then something else is loading the Foo::Bar module and I may as well make the loading explicit, though this is an annoying code smell -- I have two hundred test programs to fix!)


Devel::TraceLoad?

AndyArmstrong on 2007-12-11T12:40:47

Does Devel::TraceLoad help at all?

Re:Devel::TraceLoad?

Ovid on 2007-12-11T14:15:34

It would certainly help, but it merely tells me what loaded what, not if that loaded item is being used. My little hack tells me that the module was really loaded and after I delete the 'use' line, if the other tests pass and I see the module is no longer used, it shouldn't be listed. Devel::TraceLoad can't really tell me that, though it can tell me where the module is really loaded. I should really use that more.

Devel::Unplug?

AndyArmstrong on 2007-12-11T14:58:37

What about Devel::Unplug then? :)

You could probably automate finding what your tests load and then systematically using Devel::Unplug to remove each module and see check that they still pass.