How many ways can I use thee, module?

What are all the different ways that a dependency on a module can be introduced?

    use Foo::Bar;
    require Foo::Bar;
    use parent 'Foo::Bar';
    use base 'Foo::Bar';

And if you're using Moose:

    extends 'My::Parent'      => { -version => 0.01 },
            'My::OtherParent' => { -version => 0.03 };
    
    with 'My::Role'      => { -version => 0.32 },
         'My::Otherrole' => { -version => 0.23 };

Or the aliased module:

    use aliased 'Foo::Bar' => 'Foobar';
    $foobar = Foobar->new;

Or the namespace module:

    use namespace Foobar => Foo::Bar;
    $foobar = Foobar->new;

And don't forget Module::UseFrom!

    use Module::UseFrom;
    BEGIN {
        our $var = 'Foo' . '::' . 'Bar';
    }
    use_from $var; # use Foo::Bar;

Oh, and I've just come across relative:

    package BigApp::Report;
     
    use relative qw(Create Publish);
    # loads BigApp::Report::Create, BigApp::Report::Publish

What other ways are there?

Turns out, quite a few! Thanks to everyone who pointed out modules in the comments. That encouraged me to go digging, and I turned up a bunch more. Here's my current list of modules that can load other modules.

My review of modules for getting dependencies is getting out of control — 26 modules so far. I want to come up with some examples that I can use to compare and contrast the hoard.

20 Comments

How about reading the module into a variable and then eval it? And then run `Module->import();`

I use Module::Load::Conditional to load in modules in certain cases.

my $rv = check_install( module => 'LWP', version => 5.60 )
or print 'LWP is not installed!';

eval "use $module";

Don't forget "use parent" and "use base". But much more exciting: Prepare a Storable blob including an object blessed into a non-loaded class. Thaw it. It will load the class for you.

These days, I use Class::Load when I need to load a class at runtime. As a contrived example, I'd use :

load_first_existing_class(
  'Unlikely', { -version => 3 },
  'Probably', { -version => 7 },
  'Sure::Thing'
);

Module::UseFrom is more of an experiment in using Devel::Declare. Sadly the awkward BEGIN block prevents it from being as useful as I had hoped. I must say, even I don't use it. The only reason to is the 'use_if_available' function, which does some interesting things.

I should amend that. Its not the Module::UseFrom doesn't work, or isn't as safe or useful as it claims. Its just that that level of care is rarely needed and is often as easily replaced by other means.


use Module::Load;
load MODULE;

use if CONDITION, MODULE => ARGUMENTS

I

use Class::Load 0.20 qw( load_class );

my $objload_class('Foo::Bar')->new(...);

one of the benefits of Class::Load is that it checks if the library is already loaded before attempting to load again. My understanding is that other runtime methods will simply compile the library again.


use Class::Load 0.20 qw( load_class );
my $obj = load_class('Foo::Bar')->new(...);

Also someone should mention Module::Runtime and it's various methods, which Class::Load depends on.

Hey cool! Like I said, its not without value :-)

Oh, too bad. Ron, you should probably remove that unused dependency. (sad trombone)

Hi Joel

I read these comments expecting to learn something, but what I learned is that I have more work to do. That'll teach me...

Hi Neil

Actually, the problem is immeasurably worse than that.

While composing a reply to a post on the Graphviz mailing list, I found a disastrous bug in the output of my code, so the work is to find the cause....

Patches welcome. Hahahahahahahaha.

Leave a comment

About Neil Bowers

user-pic Perl hacker since 1992.