Adam Kennedy wrote:
>Modules don't declare dependencies on distributions, and never have.
True. But it's distributions that have the optional_features.
>They declare dependencies on APIs, described as namespace/version pairs.
So to fit in with this system, we could arrange for each optional feature
of a distribution to be reified as a module. Consider the case I ran
into, where I want to declare a dependency on the C language support
aspects of Module::Build. We can name this "Module::Build::C_support",
or something similar. There'd be a Module-Build-C_support distribution,
with a META.yml containing
name: Module-Build-C_support
version: 0.01
requires:
Module::Build: 0
ExtUtils::CBuilder: 0.15
provides:
Module::Build::C_support:
file: C_support.pm
version: 0.01
C_support.pm could almost be an empty file. It would only ever be
"use"d or "require"d in order to check its existence and version number.
It would contain roughly
package Module::Build::C_support;
our $VERSION = "0.01";
1;
It could also have some POD to explain the arrangement, of course.
It could additionally load the prerequisite modules, to act as a (minimal)
runtime dependency test:
package Module::Build::C_support;
use Module::Build;
use ExtUtils::CBuilder 0.15;
our $VERSION = "0.01";
1;
Then the Crypt-MySQL distribution can declare, perhaps automagically:
build_requires:
Module::Build: 0
Module::Build::C_support: 0
This would express all the dependency relationships correctly,
without Crypt-MySQL needing to know the internals of Module::Build.
The dependencies would also be understood and correctly processed
by today's CPAN.pm. The (only?) downside is having an extra, small,
distribution on CPAN for each optional feature.
> (because configure_requires isn't quite ready for
>prime time yet).
I think you're referring here to something else I was wondering about
dependencies. build_requires declares things that are required at the
time of running ./Build; is there any way to declare things that must
be installed before running ./Build.PL? Is that what configure_requires
is for?
I have a module, Time::UTC::Now, that needs to experimentally compile
some C code in order to determine which interfaces are available for the
main XS code to use. Currently it does this probing in Makefile.PL.
Translating into Module::Build, I'd need ExtUtils::CBuilder present
before Build.PL could run successfully.
Incidentally, on reflection I think the `optional features' of
my numeric modules are actually best handled as a "conflicts".
That is, Date::ISO8601 does not really depend on Math::BigInt>=1.64
(as it currently declares), but it conflicts with Math::BigInt<1.64.
META.yml solves a problem for me there.
I noticed a problem in the definition of the "conflicts" section of
META.yml. Hypothetically, suppose that my Date::ISO8601 module could
work with any Math::BigInt from 1.64 on *except* for 1.70. In reality
there is no such exception, but the version syntax of META.yml allows
for such, because I can declare the positive dependency thus:
requires:
Math::BigInt: >=1.64, !=1.70
But how would I declare this in the negative form? I essentially want
to do
conflicts:
Math::BigInt: <1.64
Math::BigInt: ==1.70
but of course I can't duplicate the "Math::BigInt" key. I would need
a logical-OR syntax:
conflicts:
Math::BigInt: <1.64 or ==1.70
-zefram