CPAN modules that (can) load other modules

other reviews

Neil Bowers

2013-03-09

This article is a review of CPAN modules that can be used to load other modules. Actually, it's less of a review and more of a travelogue. The modules described below can do a range of things, including:

If you don't want to read the whole text (there are currently 43 modules), skip to the Comparison section, which presents all the modules roughly grouped by capability. And then Conclusion suggests modules for specific tasks.

The following is a list of the modules I'm aware of so far. Please let me know if I've missed any: neilb at cpan dot org.

Module Doc Version Author # bugs # users Last update
above pod 0.40 Anthony Brummett 2 1 2013-02-25
Acme::require::case pod 0.007 David Golden 0 0 2013-02-28
again pod 0.03 Neil Bowers 0 0 2013-02-23
aliased pod 0.31 Curtis "Ovid" Poe 2 74 2013-02-18
all pod 0.5101 Piotr Roszatycki 1 0 2008-12-05
AnyLoader pod 0.04 Michael G Schwern 0 0 2000-11-29
autouse pod 1.07 Florian Ragwitz 2 3 2012-09-11
base pod 2.18 Rafaël Garcia-Suarez 4 372 2012-03-31
Class::Autouse pod 2.01 Adam Kennedy 5 15 2012-02-03
Class::LazyLoad pod 0.04 Rob Kinyon 0 0 2005-02-10
Class::Load pod 0.20 Dave Rolsky 1 151 2012-07-15
Class::Load::XS pod 0.06 Dave Rolsky 0 2 2012-10-08
Class::Loader pod 2.03 Vipul Ved Prakash 1 3 2005-04-28
ClassLoader pod 1.00006 Frank Seitz 0 0 2010-06-15
Devel::UseAnyFunc pod 1 Matthew Simon Cavalletto 0 2 2003-08-28
if pod 0.0601 Ilya Zakharevich 1 29 2010-12-01
lib::require::all pod 0.01 Tatsuhiko Miyagawa 0 0 2012-11-09
MAD::Loader pod 2.000003 Blabos de Blebe 0 0 2013-03-03
Module::Find pod 0.11 Christian Renz 3 56 2012-05-22
Module::Hash pod 0.001 Toby Inkster 0 1 2012-11-23
Module::Implementation pod 0.06 Dave Rolsky 2 7 2012-02-12
Module::Load pod 0.24 Chris Williams 1 125 2013-02-01
Module::Load::Conditional pod 0.54 Chris Williams 1 35 2012-08-12
Module::Quote pod 0.001 Toby Inkster 0 0 2012-11-23
Module::Recursive::Require pod 0.04 Masahiro Funakoshi 0 3 2006-09-03
Module::Require pod 0.05 James G Smith 1 0 2004-03-05
Module::Requires pod 0.03 Kazuhiro Osawa 0 0 2009-12-25
Module::Runtime pod 0.013 Andrew Main (Zefram) 5 42 2012-02-16
Module::UseFrom pod 0.03 Joel Berger 3 0 2012-01-06
modules pod 0.04 Murat Ünalan 0 1 2002-06-25
Mojo::Loader pod 3.89 Abhijit Menon-Sen 0 211 2013-03-04
Mrequire pod 0.006 Norbert Gövert 0 0 2003-12-08
namespace pod 0.05 Albert Michauer 1 0 2001-10-06
Object::Trampoline pod 1.26 Steven Lembark 0 0 2009-07-26
only pod 0.28 Ingy döt Net 11 5 2005-04-25
parent pod 0.225 Max Maischein 4 836 2011-03-08
pkg pod 0.03 Diab Jerius 0 0 2013-03-06
provide pod 0.03 Belden Lyman 0 1 2013-02-13
relative pod 0.04 Sébastien Aperghis-Tramoni 0 2 2008-02-02
superclass pod 0.002 David Golden 0 0 2013-02-25
syntax pod 0.004 Robert 'phaylon' Sedlacek 2 21 2012-05-18
UNIVERSAL::require pod 0.13 Michael G Schwern 7 208 2009-03-30
use pod 0.05 ☻ 唐鳳 ☺ 1 0 2012-10-21

I started this list while looking at modules for getting dependency information. Some of those modules parse code looking for explicit dependencies:

use Foo::Bar;
require Foo::Bar;
use parent 'Base::Class';

But I realised there were more modules on CPAN that should be considered as well, so started looking for them...

The modules described here each provide some mechanism for implicitly or explicitly loading a module. This may be something as simple as:

sub load_module {
    my $module = shift;
    eval "use $module";
}

Each module will be presented in turn, with a comparison and conclusion at the end.

above

above loads a module from "somewhere above you" in the directory path to the calling code, even if that directory isn't in @INC.

For example, let's say you have modules Foo::Bar and Foo::Bar::Baz, and a script mytool. You have the following directory structure:

 +-- lib
     |
     +---Foo
         |
         +-- Bar.pm
         |
         +-- Bar
             |
             +-- Baz.pm
             |
             +-- mytool

If the mytool script wants to use Foo::Bar, you can use the following:

use above 'Foo::Bar';

The version on CPAN (0.392) has a bug: if the module you're using exports some symbols, they don't get imported into the calling namespace. I've submitted a pull request for a fix to this.

I'm not really sure of a scenario where I'd use this module. The documentation says "Do NOT use this in modules, or user applications", and that it's used for "Command modules which are developer tools". It's part of the UR dist, and is used in some of it modules, as well as scripts that are part of its testsuite.

Acme::require::case

Acme::require::case overrides the require built-in with a version which does a case-sensitive check of the module name.

If you're running Perl on a case-insensitive filesystem (as I am: MacOSX), then by default you don't have to get the case of module names right. But if you run the following:

use Acme::require::case;

use Module::path qw(module_path);

print "path = ", module_path('Acme::require::case'), "\n";

It will die with the following message:

Module/path.pm has incorrect case (maybe you want Module/Path.pm instead?) at ./acme-require-case.pl line 8.
BEGIN failed--compilation aborted at ./acme-require-case.pl line 8.

You probably wouldn't include this in your code, not least because it's a lot slower than the built-in require, but you might do a one-off check:

perl -MAcme::require::case myprogram.pl

again

again provides a mechanism for reloading a module if it has changed on disk since it was first / previously loaded.

The following illustrates the module's use:

use again 'Module::Path', qw(module_path);
use again;

print "path to again: ", module_path('again'), "\n";

# ... time passes ...

require_again('Module::Path');
Module::Path->import('module_path');

print "path to again: ", module_path('again'), "\n";

You initially use again to load the module of interest use; this is just like using use directly, apart from:

You then have to use the module again, this time without any arguments. This imports the require_again function.

When you're ready to reload the module, pass the module name to require_again(). This checks whether the module has changed on disk, and if it has, reloads it and updates its internal timestamp for the module. If you explicitly imported something from the module, you'll need to do it again, otherwise you'll be calling the previous version.

The interface doesn't feel very natural. The original author Juerd Waalboer has given me co-maintenance: so far I've just done documentation updates, but I may think about changes to the interface.

aliased

aliased is a neat little module by Ovid which lets you refer to a class using a shorter name. This can be handy if you're referring to a class with a name like CPAN::Testers::Reports::Query::JSON::Set. The following shows the simplest usage:

use aliased 'Parse::HTTP::UserAgent';

$ua = UserAgent->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

By default it takes the last part of the class name to be the new class name. You can override this behaviour, and provide a new class name:

use aliased 'Parse::HTTP::UserAgent' => 'UA';

$ua = UA->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

If you use aliased without any arguments, it exports the function alias, which can be used to provide a variable alias:

use aliased;

my $userAgent = alias 'Parse::HTTP::UserAgent';

$ua = $userAgent->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

That's it really. Look at the documentation to see how import arguments are handled. The only downside is that you can't specify a minimum version of the module being used.

At the time of writing the latest version on CPAN was 0.31. The documentation says:

Also, don't let the version number fool you. This code is ridiculously simple and is just fine for most use.

I've submitted a bug suggesting Ovid bump the version to 1.00.

all

The all pragma is used to load all modules under a given namespace. The following script loads all Module::* modules, and then just uses Module::Path and Module::Version

use all 'Module::*';

print "path    = ", Module::Path::module_path('all'),    "\n";
print "version = ", Module::Version::get_version('all'), "\n";

As with any module like this, you need to be careful: the above code ends up loading 221 modules on my machine!

If a module fails to load, then all catches this and warns. Another downside to all: it doesn't provide any mechanism for finding out what modules were loaded. Obviously you could interrogate %INC, but a better interface would let you find out what modules were loaded, and what modules failed to be loaded.

AnyLoader

This is one of those modules on CPAN that just seems a bit freaky, but in a good way. If you use AnyLoader, then you you can just call functions with a fully-qualified name, without having to load them first:

use AnyLoader;

print "path = ", Module::Path::module_path('AnyLoader'), "\n";

The first time you try and use a function this way, AnyLoader will require the module for you.

If you find that just a bit too scary, you can provide a list of module names, and AnyLoader will only autoload those classes, if implicitly used:

use AnyLoader qw('Module::Path');

print "path = ", Module::Path::module_path('AnyLoader'), "\n";

With no AnyLoader you can explicitly exclude certain module names:

use AnyLoader;
no AnyLoader qw('Carp');

print "path = ", Module::Path::module_path('AnyLoader'), "\n";

This relies on a deprecated feature, so I guess it might stop working with some future version of Perl 5. It works on 5.16.2.

autouse

autouse will automatically load a module for you the first time you try and use a named function.

use autouse 'Module::Path' => qw(module_path);

print "path = ", module_path('autouse'), "\n";

It's similar to AnyLoader (described above), with the difference being that you have to explicitly list the module(s) that you want automatically loaded, and the functions that will trigger it.

As with AnyLoader, you can't specify the minimum version of the module when you autouse it.

base

The base pragma is used to specify one or more parents for the invoking class to inherit from:

package MyClass;
use base 'ParentClass';

The above code is equivalent to:

package MyClass;
BEGIN {
    require ParentClass;
    push(@ISA, 'ParentClass');
}

The documentation says that in general you should use the lighter parent pragma for this job, unless you're using the fields pragma in your class as well.

You can't specify a minimum version of the base class; if you want to do that, you should look at inherit, described below.

Class::Autouse

Class::Autouse provides lazy-loading of a class: it will delay loading of the class until the first time you try and invoke a class method:

use Class::Autouse qw(Parse::HTTP::UserAgent);

# Parse::HTTP::UserAgent hasn't been loaded at this point

$ua = Parse::HTTP::UserAgent->new('amaya/11.3.1 libwww/5.4.1');

# Parse::HTTP::UserAgent has now been loaded

print "browser = ", $ua->name, "\n";

One thing to be aware of when using this module: after running use Class::Autouse qw(Parse::HTTP::UserAgent) then %INC will appear to show that Parse::HTTP::UserAgent has been loaded, but the value will be 'Class::Autouse' rather than the path to the module. This prevents a subsequent explicit use Parse::HTTP::UserAgent from loading the class before Class::Autouse does.

You can also use this module in 'super loader' mode, where you don't have to explicitly list the modules you want automatically loaded:

use Class::Autouse ':superloader';

$ua = Parse::HTTP::UserAgent->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

Superloader mode is the same as the default mode for AnyLoader.

There's quite a bit more to this module — see the documentation. as witnessed by the thorough documentation, and the fact that it

Class::LazyLoad

Class::LazyLoad is one of a number of modules on CPAN (eg Object::Realize::Later & Class::LazyObject) which provide lazy instantiation of objects.

You can use Class::LazyLoad in a number of ways, but the following is the one most relevant to this review:

use Class::LazyLoad 'Parse::HTTP::UserAgent';

$ua = Parse::HTTP::UserAgent->new('amaya/11.3.1 libwww/5.4.1');

# class isn't instantiated until we call a method:
print "browser = ", $ua->name, "\n";

If you have a class that is expensive to instantiate, and where sometimes you end up not invoking any methods on an object, then Class::LazyLoad will save you some (run-)time.

It intercepts the constructor for your class, and defers construction until you really need an instance. Typically this is by calling one of your methods, but as the documentation explains, there's at least one other situation where the object will be instantiated (calling can()).

Class::Load

Class::Load provides a function for loading a class at run-time, and some related utility functions.

The load_class() function addresses a deficiency of require: you can't say require 'Foo::Bar' or require $class.

use Class::Load 'load_class';

load_class('Parse::HTTP::UserAgent');
$ua = Parse::HTTP::UserAgent->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

If the module couldn't be loaded for some reason, it will throw an error.

You can specify a minimum version of the module, by passing the -version option after the class name:

load_class('Parse::HTTP::UserAgent', { -version => 0.35 });

Class::Load provides four other functions, all of which can take the optional -version argument:

Under the hood, Class::Load uses Module::Runtime, so if you used that directly, you'd save yourself some dependencies.

Class::Load::XS

Class::Load::XS provides an XS implementation of parts of Class::Load, which is described above.

If you've got Class::Load::XS installed, then use'ing Class::Load will result in you using Class::Load::XS. This is achieved using Module::Implementation, which is described below.

Class::Loader

Class::Loader is used to load a module at run-time, and then instantiate it. Here's an example of the simplest usage:

use Class::Loader;

$ua = Class::Loader->_load(Module      => 'HTML::ParseBrowser',
                           Constructor => 'new',
                           );
$ua->Parse('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

If you include CPAN => 1 in the arguments to _load(), then if the module isn't installed locally, it will try and install it with the CPAN module.

Class::Loader also provides a mechanism for storing a configuration (using method _storemap), which you can refer to by name later. I couldn't get this working, as the code doesn't match the documentation.

ClassLoader

ClassLoader is the equivalent of AnyLoader, but for classes. If you use ClassLoader, then you can instantiate classes without having to use them first:

use ClassLoader;

$ua = Parse::HTTP::UserAgent->new('amaya/11.3.1 libwww/5.4.1');

print "browser = ", $ua->name, "\n";

There's plenty of documentation for ClassLoader, but unfortunately for me it's in German, so I can't tell you much more about it. It does work though.

Devel::UseAnyFunc

Devel::UseAnyFunc lets you load one of a number of equivalent functions from different modules, aliasing it to your preferred name. There are a lot of cases on CPAN where multiple modules provide essentially the same function; this lets you use whichever is available, possibly in order of preference of performance.

The following example is based on the SYNOPSIS from the documentation:

use Devel::UseAnyFunc 'url_esc',
                                 'URI::Escape'          => 'uri_escape',
                                 'HTML::Mason::Escapes' => 'url_escape', 
                                 'CGI::Util'            => 'escape';

my $query   = 'perl 7 heresy!';
my $encoded = url_esc($query);

print "URL      = '$query'\n";
print "SAFE URL = '$encoded'\n";

You can turn on diagnostics by setting $Devel::UseAnyFunc::DIGANOSTICS = 1 in a BEGIN block.

I started this review because I was interested in modules that might hide dependencies from code that's parsing source to determine dependencies. If you used Devel::UseAnyFunc, which of the modules would you list as a dependency? Presumably the last one in the list, to ensure you always get an implementation of the function you want.

if

The if pragma provides conditional loading of a module:

use if CONDITION, MODULE => ARGUMENTS;

The following unrealistic example only loads Module::Path if it's running on Perl 5.16.2 or later:

use if $] >= 5.016002, 'Module::Path' => qw(module_path);
print "path = ", module_path('if'), "\n";

The documentation isn't very helpful, and I couldn't think of a real use for it. But I realised that there are other dists using the if pragma, so I had a look at some of them.

The following mechanism is used to deprecate core modules beyond a certain version of Perl. This is from Text::Soundex 3.04:

use if $] > 5.016, 'deprecate';

Another example, from Attribute::Lexical; this loads mro if running on Perl 5.9.5 or later:

use constant _KLUDGE_FAKE_MRO => "$]" < 5.009005;
use if !_KLUDGE_FAKE_MRO, "mro";

And finally, from the testsuite for File::Map, the following imports two functions from POSIX, as long as it's not running on Windows:

use if $^O ne 'MSWin32', POSIX => qw/setlocale LC_ALL/;

If Perl 5 was on github, I'd probably write some more documentation for this module and submit a pull request.

lib::require::all

lib::require::all will load all modules (*.pm) in a given directory. By default it will load everything in the lib directory, but you can override this by specifying the directory when you use lib::require::all

use lib::require::all 'lib/Module';

print "path = ", Module::Path::module_path('lib::require::all'), "\n";

The other modules for bulk-loading modules let you specify the start of the namespace. This module would be useful when loading modules included in a distribution, or some modules used in a testsuite.

You could use it to load all modules in a given namespace, though it's not quite as user-friendly as the other modules. Let's say you want to load all the Module::* modules you've got installed.

use lib::require::all 'lib/Module';

print "path = ", Module::Path::module_path('lib::require::all'), "\n";

But what's happening here is:

There's a potential gotcha if you use it this way: it's not uncommon for there to be a module Foobar::Plugin::Cool::Module, which is a plugin wrapper around Cool::Module. If you've done use lib::require::all '.../lib/Foobar/Plugin' and then later on compilation hits use Cool::Module, it will already think it's been loaded, but it hasn't. Pretty esoteric, I know, especially when this module is really intended for cases where you want:

use lib::require::all 'lib';

In which case you don't need to specify 'lib', as that's the default.

MAD::Loader

MAD::Loader is useful where you might want one or more of a number of modules loaded, but not always.

use MAD::Loader;

my $loader = MAD::Loader->new(
                prefix   => 'Module',
                on_error => sub { print "oops: $_[0]\n" },
             );
$loader->load(qw(Path Version));

print "path    = ", Module::Path::module_path('MAD::Loader'),    "\n";
print "version = ", Module::Version::get_version('MAD::Loader'), "\n";

You configure the loader with the prefix part of the modules you want to load. This might be the prefix for your plugins, such as Template::Plugin.

You then call the load method to load up one or more modules. By default it will search for modules in @INC, but you can provide your own list of directories with the set_inc option.

This can do quite a bit more than shown above. You can pass a method name with the initializer option to the MAD::Loader's constructor. If you provide one, then this class method will be invoked on all classes loaded.

You can also provide an error handler, which will be called if a module fails to load. Unfortunately the error handler is just passed the text of the failure message; it would be more helpful if it was passed the name of the module as well.

Another improvement would be if you could pass a pattern to the load method, or some way to specify "all modules with the given prefix". That would make this a a more generally useful module for loading plugins.

Module::Find

Module::Find provides functions that can be used to find and optionally load all modules in or under a given namespace.

To find all Template Toolkit plugins installed locally, you could write:

use Module::Find;

my @plugins = findallmod('Template::Plugin');
print "found ", int(@plugins), " plugins\n";

The findsubmod() function is similar to findallmod(), but only returns modules who are immediately within the specified namespace. So if you used it in the above example, it would return Template::Plugin::DBI, but it wouldn't return Template::Plugin::HTML::Template

The useall() and usesub() functions are similar to the functions described above, but they load the modules and then return a list of the modules loaded. They will die if any of the individual modules fail to load.

By default it will look for modules in @INC; you can provide your own list of directories to search, with the setmoduledirs() function.

Module::Hash

Module::Hash is a quirky module from Toby Inkster. It provides a tied hash which automatically loads modules for you. "Why would you want to do that?" I hear you ask. Good question, read on.

The following shows the explicit tied interface:

use Module::Hash;
        
tie my %MOD, "Module::Hash";
        
my $ua_string = 'amaya/11.3.1 libwww/5.4.1';
my $ua        = $MOD{'Parse::HTTP::UserAgent'}->new($ua_string);
print "browser = ", $ua->name, "\n";

You can remove the explicit tie by passing a hashref when use'ing Module::Hash:

use Module::Hash \%MOD;
        
my $ua_string = 'amaya/11.3.1 libwww/5.4.1';
my $ua        = $MOD{'Parse::HTTP::UserAgent'}->new($ua_string);
print "browser = ", $ua->name, "\n";

On the positive side, you can specify a minimum version for the module you're using:

$ua = $MOD{'Parse::HTTP::UserAgent 0.35'}->new($ua_string);

Why might you want to use this module? Toby points out that Math::BigInt->new(...) is ambiguous, as you could define a function BigInt() in the Math package. While that's true, I don't think this is the solution to that, and somehow I suspect Toby doesn't either!

This really seems like an experiment, and as such I don't think it should be on CPAN. But wait, you say, if you look at the module summary at the start of this review, there's another dist on CPAN that uses Module::Hash. That's Module::Quote, another of Toby's experiments, described below...

Module::Implementation

Module::Implementation is useful where you have multiple implementations for a common interface, and don't really mind which is used (but might have a preference), as long as one of them can be. A common example in the Perl world is where you have a pure perl implementation, and an XS one. The following example is lifted straight from the SYNOPSIS:

package Foo::Bar;

use Module::Implementation;

BEGIN {
    my $loader = Module::Implementation::build_loader_sub(
                    implementations => [ 'XS',  'PurePerl' ],
                    symbols         => [ 'run', 'check' ],
                  );
    $loader->();
}

This will first try to load Foo::Bar::XS, and if successful will import run() and check() into Foo::Bar. If Foo::Bar::XS wasn't found, it will try and load Foo::Bar::PurePerl, again importing the specified functions if successful.

A user of Foo::Bar then just writes:

use Foo::Bar;

# can use run() and check()

You might want to provide a library of functions, only one of which would benefit from an XS implementation. In that case, define most of the functions in the parent class (Foo::Bar in the example above), and then put the interesting function in the two subordinate classes. This is exactly what Class::Load (described above) does.

You can have as many implementations as you like: Module::Implementation will just work down the list until it loads one successfully. Some of the implementations may only be available on certain operating systems, or there might be multiple implementations that make different trade-offs of RAM / run-time / disk space.

Module::Load

Module::Load provides a load() function which will perform runtime loading of both modules and files. It addresses the same issue with require that is addressed by Class::Load, but is slightly more generic.

The following illustrates the module's use:

use Module::Load;

load Parse::HTTP::UserAgent;
$ua = Parse::HTTP::UserAgent->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

You can load a module with any of the following:

load Foo::Bar;
load 'Foo::Bar';
load $module;      # $module = 'Foo::Bar';

You can pass import arguments:

load CGI, ':standard';

But you can't specify a minimum version of the module.

Module::Load::Conditional

Module::Load::Conditional provides functions for getting information about what modules are installed locally, and loading them at run-time.

The check_install() function will see whether a module is installed locally, and tell you where, and optionally what version:

use Module::Load::Conditional qw(check_install);

$ref = check_install(module => 'Module::Path', version => 0.09);

print "Module::Path\n";
if (!defined $ref) {
    print "  not installed\n";

} elsif (not $ref->{uptodate}) {
    print "  needs updating\n";

} else {
    print "Module::Path\n";
    print "  version = $ref->{version}\n";
    print "  path    = $ref->{file}\n";
}

The can_load() function takes a hash of modules, and loads them all, if it can:

use Module::Load::Conditional qw(can_load);

$loaded = can_load(
            modules => {
                        'Module::Path'    => undef,
                        'Module::Version' => undef,
                       },
            verbose => 1,
            nocache => 0);

if ($loaded) {
    print "path    = ", Module::Path::module_path('Module::Load::Conditional'), "\n";
    print "version = ", Module::Version::get_version('Module::Load::Conditional'), "\n";
} else {
    print "failed to load Module::Path and Module::Version\n";
}

You can't provide an import list for the modules.

If verbose is true, a warning will be printed if a module fails to load; this can also be controlled with a package variable. There are six global variables which control behaviour, see the relevant section in the documentation for more details on these.

The requires() function takes a module name and returns a list of all the modules that will be loaded if you use the module. This includes immediate dependencies, their dependencies, and so on:

use Module::Load::Conditional qw(requires);

# @deps = requires('Module::Load::Conditional');
@deps = requires('Devel::Loaded');

print "Module::Load::Conditional uses the following:\n";
foreach my $module (@deps) {
    print "  $module\n";
}

This works by running perl in a sub-process, and having it load the module and then print out everything in %INC, which is captured in back-ticks. This means it can generate confusing output if the module passed prints something to STDOUT in an END block, for example. I've submitted a bug report on that, with a complete hack (partial) solution.

Module::Quote

Module::Quote is another quirky module from the mind of Toby Inkster. It's provides a quote-like operator, qm, that will load a module if it hasn't already been loaded, and return its name.

use Module::Quote;
        
my $ua_string = 'amaya/11.3.1 libwww/5.4.1';
my $ua        = qm( Parse::HTTP::UserAgent )->new($ua_string);
print "browser = ", $ua->name, "\n";

You can also specify a minimum version of the module:

$ua = qm( Parse::HTTP::UserAgent 0.35 )->new($ua_string);

Sure, it's freaky, but I like this more than its twisted sister module, Module::Hash, which is described above.

Module::Recursive::Require

Module::Recursive::Require is a class that can be used to load all modules in a given namespace. It is similar to Module::Find, but there are some key differences.

To find all Template Toolkit plugins installed locally, you could write:

use Module::Recursive::Require;

my $mrr     = Module::Recursive::Require->new();
my @plugins = $mrr->require_of('Template::Plugin');
print "found ", int(@plugins), " plugins\n";

The documentation seems to imply that this will load all modules matching Template::Plugin::*, but it seems to only match modules in Template/Plugin/. Ie it will find Template::Plugin::DBI but won't find Template::Plugin::HTML::Template.

It also lets you provide filters, which exclude modules that match provided patterns.

The documentation is a bit thin, and given the above I think you'd be better off using Module::Find: it provides more functionality, has better documentation, and appears to be still actively maintained / under development.

Module::Require

Module::Require is another module that can be used to load all modules in a given namespace. You can either specify a glob-style pattern for matching modules, or a regex.

The following uses the glob interface to load all locally installed Template Toolkit plugins of the form Template::Plugin::<name>:

use Module::Require ();

my @failed = Module::Require::require_glob( 'Template::Plugin::*' );
print "plugins loaded:\n";
foreach my $key (keys %INC) {
    print "  $key\n" if $key =~ m!^Template/Plugin/!;
}

The module has a bug: it doesn't require Exporter, so you can't import the provided functions in the way suggested by the SYNOPSIS. Another downside of the module is that it doesn't return a list of the modules loaded, but rather returns a list of any modules that failed to load.

The require_regex() function works just like require_glob(), but takes a regular expression rather than a glob pattern. The module also provides a function walk_inc(), for iterating over all modules in @INC which start with a specified path.

All in all I think you'd be better off using Module::Find.

Module::Requires

Module::Requires can be used to load one or more modules, optionally specifying version constraints. The following show basic usage:

use Module::Requires
    'Parse::HTTP::UserAgent' => 0.35,
    'HTML::ParseBrowser';

$ua = Parse::HTTP::UserAgent->new('amaya/11.3.1 libwww/5.4.1');
print "first guess  = ", $ua->name, "\n";

$ua = HTML::ParseBrowser->new('amaya/11.3.1 libwww/5.4.1');
print "second guess = ", $ua->name, "\n";

You can also specify the version using a more complex set of constraints:

use Module::Requires
    'Parse::HTTP::UserAgent' => [ '>' => 0.30, '<=' => 1.00 ];

$ua = Parse::HTTP::UserAgent->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

You can also provide import parameters:

use Module::Requires -autoload,
    'Module::Path' => {
        import  => [qw(module_path)],
        version => ['>' => 0.08, '<=' => 1.00],
    };

print "path = ", module_path('Module::Requires'), "\n";

Note that you also need to provide the -autoload option when you specify import symbols. If you include -autoload on its own, Module::Requires will call import() on all modules loaded.

The documentation for this module is a bit terse, so it took me a while (and reading of the source) to work out exactly what it can do. The main thing it adds over the other modules described here is the more flexible mechanism for specifying version constraints.

Module::Runtime

Module::Runtime provides a collection of functions that are useful for manipulating modules and their names at run-time.

The require_module() function takes a string — either literal or variable — and require's the named module:

use Module::Runtime qw(require_module);
require_module 'Module::Path';
print "path = ", Module::Path::module_path('Module::Runtime'), "\n";

my $module = 'Module::Version';
require_module $module;
print "version = ", Module::Version::get_version('Module::Runtime'), "\n";

This addresses a restriction with the require built-in, as do other modules here. But unlike Module::Load, it doesn't support the module name as a bareword. Ie the following fails:

require_module Module::Path;

You can't specify a minimum version of the module with require_module, but you can with use_module, which takes an optional second argument:

use_module 'Module::Path', 0.09;

my $module = 'Module::Version';
use_module $module, 0.12;

It returns the name of the module loaded, if successful, so you can chain it in situations like:

$object = use_module('My::Class')->new();

The module provides other things, including the following. See the documentation for the rest.

As with all modules from Andrew Main, this is a rigorous and solid module.

Module::UseFrom

I couldn't get Module::UseFrom to work on Perl 5.16.2. I've submitted a bug, and will have another go if the bug gets fixed, or I fancy having a dig in the code.

modules

modules lets you load multiple modules with a single use line:

use modules 'strict', 'warnings', { Module::Path => 'module_path' };

print "path = ", module_path('modules'), "\n";

Ok, all looks fine so far, right. Maybe you're thinking you might install it...?

Hold your horses, pardner: this module has a bonus feature: by default, if you try and use a module that's not installed, it will try and install it for you. No, really!

You can use the -force and +force options can be used to control this behaviour:

use modules 'strict', '-force', { Module::Path => 'module_path' }, '+force', 'warnings';

print "path = ", module_path('modules'), "\n";

You might decide to use this module, and always put -force at the start, but I'd rather the default was to not try and install modules for me. At least if you use CPAN::AutoINC or Module::AutoINC you're explicitly saying you want this behaviour.

Mojo::Loader

Mojo::Loader provides support functions for a plugin framework: a run-time class loader, and a method for finding all modules within a given namespace.

The following illustrates use of the class loader:

use Mojo::Loader;
$loader = Mojo::Loader->new();
$e = $loader->load('Parse::HTTP::UserAgent');
if (ref($e)) {
    die "Exception: $e\n";
} elsif ($e) {
    die "failed to load class\n";
}

$ua = Parse::HTTP::UserAgent->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

You can also find all locally installed modules under a given namespace:

use Mojo::Loader;
$loader = Mojo::Loader->new();
$listref = $loader->search('Template::Plugin');

print "Template plugins found:\n";
foreach my $module (@$listref) {
    print "  $module\n";
}

One problem with this method: it only finds modules immediately within the namespace specified. I have Template::Plugin::HTTP::UserAgent installed, but this won't be returned. I submitted a bug for this but was told "This is not a bug, but a feature".

Mrequire

Mrequire is another module which helps you load modules at run-time. The mrequire function works just like the built-in require, but you can pass the module name in a variable:

use Mrequire 'mrequire';

$module = 'Module::Path';
mrequire($module);
print "path = ", Module::Path::module_path('Mrequire'), "\n";

You can't pass any import parameters.

Mrequire can also call the constructor for a class you've presumably just loaded with the mrequire function:

use Mrequire;
my $class = 'Parse::HTTP::UserAgent';

Mrequire::mrequire($class);
$ua = Mrequire::new($class, 'amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

I'm not sure why you'd do this though, when you can just write:

$ua = $class->new('amaya/11.3.1 libwww/5.4.1');

You'd be better off looking at Module::Load or Module::Runtime, depending on your needs.

namespace

namespace lets you define an alternate name for a module ("namespace aliasing"), just like aliased, described above. The following shows the simplest usage:

use namespace UserAgent => 'Parse::HTTP::UserAgent';

$ua = UserAgent->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

If the alias starts with '::', then the alias is prefixed with the calling package name:

package Foobar;
use namespace '::UserAgent' => 'Parse::HTTP::UserAgent';

$ua = Foobar::UserAgent->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

Object::Trampoline

Object::Trampoline provides lazy instantiation of a class. Let's say you've got a class which is expensive to instantiate, or perhaps some other reason for only wanting to instantiate it when you're really sure you need it. You call the constructor for your class on Object::Trampoline and pass the name of the class as an additional first argument:

use Object::Trampoline;
use Parse::HTTP::UserAgent;

$ua = Object::Trampoline->new('Parse::HTTP::UserAgent', 'amaya/11.3.1 libwww/5.4.1');

# class isn't instantiated until we call a method:
print "browser = ", $ua->name, "\n";

It can go one step further, and provide lazy loading of your class as well. This is done by invoking the constructor on Object::Trampoline::Use:

use Object::Trampoline;

$ua = Object::Trampoline::Use->new('Parse::HTTP::UserAgent', 'amaya/11.3.1 libwww/5.4.1');

# class isn't instantiated until we call a method:
print "browser = ", $ua->name, "\n";

When you do this, you can't pass any import argument to be passed when your class is use'd. If you need to do that, use Object::Trampoline rather than Object::Trampoline::Use, and use your class directly yourself.

If you're interested in this class, you should also look at Class::LazyLoad, described above.

only

The only pragma serves two functions:

To only use a specific version of a module:

use only MyModule => '0.09';

To specify a minimum version of a module:

use only MyModule => '0.08-';

To use any version of a module within a range:

use only MyModule => '0.08-0.15';

The module can be used to keep multiple versions of modules installed; they're stored in a separate directory.

At the time of writing, the version on CPAN (0.28) doesn't work with Perl 5.16.2, and has outstanding bugs going back 10 years, so I haven't tested it.

parent

The parent pragma is a lightweight replacement for the base pragma. It is used to specify one or more parents for the invoking class to inherit from:

package MyClass;
use parent 'ParentClass';

The above code is equivalent to:

package MyClass;
BEGIN {
    require ParentClass;
    push(@ISA, 'ParentClass');
}

The parent pragma was a fork of base, with a lot of the 'cruft' removed. It has just 30 lines of code, compared to 167 for base, which has a lot of complexity for handling fields and signals.

As with base, you can't specify a minimum version of the base class; if you want to do that, you should look at superclass (described below), which is a fork of parent.

pkg

The pkg pragma is a re-imagining of the use pragma to better handle inner packages.

Let's say you've got a module A, which has two nested modules:

package A {
    use superclass 'Exporter';
    our @EXPORT_OK = qw(a);
    sub a { print "Hello from a()\n"; }

    package A::B {
        use superclass 'Exporter';
        our @EXPORT_OK = qw(ab);
        sub ab { print "Hello from ab()\n"; }
    }

    package A::C {
        use superclass 'Exporter';
        our @EXPORT_OK = qw(ac);
        sub ac { print "Hello from ac()\n"; }
    }
}
1;

And in some other bit of code you want to import the ab() function. You can't do this in a single line with the use built-in, but with pkg you can:

use pkg [ 'A' ], [ 'A::B' => qw(ab) ];

ab();

The documentation is very thorough, so if you're (interested to try) using inner packages, there's a lot more to read.

It has a number of other features. For example, it can be used like the aliased pragma (described above), to define a short name for a class, either by just taking the last part of the class name:

use pkg -alias => 'Parse::HTTP::UserAgent';

$ua = UserAgent->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

Or specifying an entirely new alias, with the slightly clumsy notation:

use pkg 'Parse::HTTP::UserAgent' => -as => 'UA';

$ua = UA->new('amaya/11.3.1 libwww/5.4.1');
print "browser = ", $ua->name, "\n";

provide

provide will load different modules depending on which version of Perl is running:

package My::Module;

use provide (
    if => ge => '5.013000' => 'My::Module::v5_013000',
    else                   => 'My::Module::v5_080000',
);

With a more recent version of Perl you might be able to provide a more efficient implementation, and using this provide, you can ensure that your module can be used with older versions of Perl as well.

This is a sister module, in spirit, to Module::Implementation which provides a different mechanism for loading alternate implementations.

relative

relative lets you load modules by specifying names relative to the calling package name.

In my module Mail::SendGrid you'll see code similar to:

package Mail::SendGrid;
use Mail::SendGrid::Bounce;

Instead I could write:

package Mail::SendGrid;
use relative Bounce;

And if I had more than one subordinate class, I could load them with a single line:

package Mail::SendGrid;
use relative qw(Bounce Block);

In the above example, I'd still write $bounce = Mail::SendGrid::Bounce->new(...), but you can also define an alias for the class (as you can with aliased and namespace):

package Mail::SendGrid;
use relative -aliased => Bounce;
...
$bounce = Bounce->new(...);

When I discovered this module my first thought was "Ooh, I'll use that!". But then I thought about someone else coming across the following line in my code, and perhaps wondering what it does:

use relative qw(Bounce Block);

You could argue that this module increases the cognitive load for someone reading your code, and adds a dependency. But now I know about it, will I use it in production...

superclass

The superclass pragma was forked from the parent pragma (described below), to add module version checks. It is used to specify one or more superclasses for the invoking class:

package MyClass;
use superclass qw(Foo Bar), 'Baz' => 1.23;

The above code is equivalent to:

package MyClass;
BEGIN {
    require Foo;
    require Bar;
    require Baz;
    Baz->VERSION(1.23)
    push @ISA, qw(Foo Bar Baz);
}

Given that base and parent don't let you specify a version, I might switch to this module.

syntax

The syntax pragma loads syntax extensions in the Syntax::Feature namespace.

For example, Syntax::Feature::Method provides a method keyword; you can use this with:

use syntax 'method';

method foo($n)
{
    return $n * $self->bar;
}

UNIVERSAL::require

UNIVERSAL::require adds a universal require() class method which lets you do the following:

$module = 'Module::Path';
$module->require();

instead of the following (which you have to do due to the limitations of the require built-in):

$module = 'Module::Path';
eval "require $module";

You can optionally specify a minimum version of the module:

use UNIVERSAL::require;

$class = 'Parse::HTTP::UserAgent';
$class->require(0.35);

The module also provides a universal use() class method. The following is lifted straight from the documentation:

my $require_return = $module->use           or die $@;
my $require_return = $module->use(@imports) or die $@;

As of 2010, MSCHWERN considers this deprecated, and suggests you look at Module::Load (described above).

use

The use pragma lets you load multiple modules with a single statement:

use use 'strict', 'warnings', 'Module::Path';

print "path = ", Module::Path::module_path('use'), "\n";

The documentation says you can specify import parameters, but the following doesn't work with use 0.05 on Perl 5.16.2:

use use Module::Path => ['module_path'];

print "path = ", module_path('use'), "\n";

This module basically does the same thing as the modules pragma, but it doesn't try and install modules for you (a good thing in my book). Furthermore, the documentation says that use works with syntax-altering modules like Devel::Declare, but modules doesn't.

I think the name of this module is confusing: on first seeing use use qw(strict warnings); people might think it's a typo.

Comparison

The modules described here do quite a range of things, so there aren't really any tests we can use to run a bake-off. Instead, here they are grouped by the kind of function provided:

Some modules really belong to more than one of these categories, so for a future version I might try and come up with some kind of Venn diagram.

Given the space covered by these modules, in the next section I try to recommend which module(s) you might to use for specific needs.

Conclusion

Given the range of features described, there's obviously not one size to fit all, so here are some thoughts on what to use where and when:

comments powered by Disqus