Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

How do you uncover needless module loads or missing loads in code.

by iiijjjiii (Novice)
on Jul 15, 2009 at 18:51 UTC ( #780433=perlquestion: print w/replies, xml ) Need Help??
iiijjjiii has asked for the wisdom of the Perl Monks concerning the following question:

I find the following crop up in scripts as they are maintained over time.

1. Load a module that is never used.

#!/usr/bin/perl use strict; use Foo; use Bar; # Needless my $foo = Foo->new();

2. Forget to explicitly load a module.

#!/usr/bin/perl use strict; use Foo; my $bar = Bar->new(); # Works because Bar is loaded by Foo

In a separate module...

package Foo; use Bar; sub new { ... }

If package Foo is ever modified such that it no longer uses Bar, the script goes kaboom.

Any suggestions on how to reveal these in scripts other than scanning the code? Do you use any practices to prevent them?

Replies are listed 'Best First'.
Re: How do you uncover needless module loads or missing loads in code.
by toolic (Bishop) on Jul 15, 2009 at 19:12 UTC
Re: How do you uncover needless module loads or missing loads in code.
by hesco (Deacon) on Jul 15, 2009 at 21:57 UTC
    I'm dealing with a related but dissimilar issue myself at: fastcgi broke my Exports

    (Please ignore my rush to judgement conveyed in the unfortunate title. I now suspect that fastcgi had nothing to do with this, still unresolved, issue).

    In my attempts to sort out my own issue, I added the following debug code to my script:

    { $ENV{PATH} = "/bin"; foreach my $module (keys %INC){ my $result = `grep '^sub import' $INC{$module}`; if ($result){ print STDERR "The module: $module includes: \n$result \n"; } if($module =~ m/Account/){ print STDERR "The next module is: $module \n"; print STDERR `grep _GenerateAccountSummary $INC{$module}`; print STDERR "\n\n"; } } }
    I've been using Data::Dumper to Dump(\@INC,\%INC,\%::,\%This::Module::,\%That::Module::), etc. Perhaps you might find these techniques helpful as well.

    -- Hugh

    if( $lal && $lol ) { $life++; }
Re: How do you uncover needless module loads or missing loads in code.
by ELISHEVA (Prior) on Jul 16, 2009 at 09:34 UTC

    First things first, I would look at why a script is going kaboom when something is no longer used. Isolate the problematic design pattern and then replace it with something that is not so delicate. Under normal coding circumstances a loaded but unused module simply sits there, not bothering anyone. At worst it takes up a small amount CPU cycles to compile and a bit of memory to keep around, but that is about the cost of it.

    For example, if the script is going kaboom because the module no longer exists on your system, maybe you want to replace use blah with something that checks first to see if the module is on the system before trying to load it. There are a large number of modules on CPAN that can be used to construct something like that. Among them: Module::Optional, Module::Pluggable, Module::Best, Module::maybe, Module::only, Module::Load::Conditional.

    Trying to find loaded but unused modules is not an easy task, even in strongly typed languages like Java. At best you will get approximate results:

    • Classes and modules can be loaded at runtime using a name created from a dynamically generated string or even a class name located in a user configuration file. There is no way to know in advance with certainty the full set of classes to be used during runtime.
    • The class to which an object belongs is not necessarily the class that defines its methods. An object's methods can come from any of its super classes. In addition to finding anything that looks like a class name, you will have to navigate recursively to all the superclasses of that class and add them to the list of all classes in use.
    • Identifying what looks like a class name is also at best an estimate, at least in Perl. Module files can contain multiple packages. The package names usually are the same as the module file, but not always. Objects and classes are defined by convention and are not hard coded into the language. Inheritance is defined using @ISA variable. Although it isn't good programming practice to do this, you can dynamically change the list of parent classes at runtime. Well written code will observe the convention of using new for an object constructor. But there is nothing stopping someone from using new for an entirely different purpose because "new" isn't a reserve word in Perl. Additionally, even good programmers need to have more than one constructor and sometimes name those additional constructors something other than new. For example, Test::Builder uses new to return a global test builder and create to return a freshly allocated test builder object. Sometimes people will use the input source as part of the name, e.g. "newFromFile", "newFromDB", etc.

    If estimates are OK for your purposes, then you might want to take a look at PPI. However, make very sure you have a very good test suite that covers all code and considers all configuration files that might affect what modules are loaded. Otherwise, you may find you nixed a dependency that is in fact in use. Been there. Done that.

    Best, beth

Re: How do you uncover needless module loads or missing loads in code.
by GrandFather (Sage) on Jul 16, 2009 at 10:16 UTC

    Your issue seems to be "How do I prevent redundant module loads" rather than "How do I detect unused modules". If that is the case then don't worry about it. Perl only loads the module once so the "extra" use statements do not represent a significant processing hit. They do however provide useful documentation - they indicate that the code requires those modules. So long as the "extra" use statements aren't causing trouble due to module load order issues or some such, leave them be!

    True laziness is hard work

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://780433]
Approved by ikegami
Front-paged by grinder
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (7)
As of 2017-03-30 21:39 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (364 votes). Check out past polls.