perl5ever has asked for the wisdom of the Perl Monks concerning the following question:

I was wonder if anyone has found it valuable to distinguish between compile-time and run-time module dependencies.

Example - in this case the module Fcntl is a compile-time dependency of module Bar:

package Bar; use Smart::Comments; sub blather { ### $foo }

However, in this example, LWP::UserAgent is just a run-time dependency of module Foo:

package Foo; use LWP::UserAgent; sub make_agent { LWP::UserAgent->new }
It could also be written like this:
package Foo; # NOTE: this module needs LWP::UserAgent loaded in order to work sub make_agent { LWP::UserAgent->new }
It would then be some other code's responsibility to ensure that LWP::UserAgent was loaded before any subs in package Foo were called.

Specifically, a compile-time dependency is a module which needs to be loaded in order for a compile-check to work. A run-time dependency is one that only required to be loaded at run time.

So the question again - has anyone found it useful to formally declare a module's run-time only dependencies - perhaps with a pragma like:

use runtime LWP::UserAgent;

Replies are listed 'Best First'.
Re: use: distinguishing compile-time vs run-time dependencies
by chromatic (Archbishop) on Aug 08, 2011 at 00:59 UTC

    That sounds like dependency injection (part of the larger system of inversion of control). I hadn't thought of a formal specification for such things, but that's an interesting concept.

    See perhaps Bread::Board for practical uses.

    A injection framework might even export a constant of the appropriate name (LWP::UserAgent) such that the IoC registry could get the appropriate class object. Interesting.

Re: use: distinguishing compile-time vs run-time dependencies
by moritz (Cardinal) on Aug 08, 2011 at 01:06 UTC
      require basically does the job, but it could be useful to be able to gather the use information more formally.
      One advantage of a 'use'-pragma to declare the run-time dependency is that the module name can be checked at compile time, e.g.:
      use required Some::Module;
      can verify that Some::Module is in the @INC path at compile time. Simply using require Some::Module won't do that.
Re: use: distinguishing compile-time vs run-time dependencies
by Khen1950fx (Canon) on Aug 08, 2011 at 01:10 UTC
    I used Module::Runtime. For example:
    #!/usr/bin/perl use strict; use warnings; use Test::More tests => 3; BEGIN { use_ok "Module::Runtime", qw(use_module); } my $run = use_module("LWP::UserAgent", 6.02); my ($result, $err); sub test_use_module($;$;) { my($name, $version) = @_; $result = eval { use_module($name, $version ) }; $err = $@; } test_use_module("LWP::UserAgent", 6.02); is( $err, "" ); is( $result, "LWP::UserAgent");
Re: use: distinguishing compile-time vs run-time dependencies
by JavaFan (Canon) on Aug 08, 2011 at 10:11 UTC
    Specifically, a compile-time dependency is a module which needs to be loaded in order for a compile-check to work. A run-time dependency is one that only required to be loaded at run time.
    That isn't very different than solving the halting problem, isn't it? Suppose a module "Dependency::Checker" exists, which exports a subroutine runtime_dependency that does what it says:
    package Foo; use Dependency::Checker 'runtime_dependency'; use LWP::UserAgent; sub make_agent {LWP::UserAgent->new} BEGIN { make_agent() if runtime_dependency("LWP::UserAgent"); } 1;
    What will happen?
      I'm not asking for a why to figure out what kind of dependency a module is. I'm just asking whether it is useful to _declare_ what kind of dependency a module is.
        Well, unless the declaration isn't enforced (that is, it's only informative), it's the same problem. But if it's only informative, you can already do this; it's called "comments".