When creating a CPAN distribution, all the modules should come under a single
namespace. If your Foo-Bar
distribution has a lead module Foo::Bar
,
then in almost all cases,
all other modules in your distribution should be in the Foo::Bar::*
namespace.
In this post I'll explain why.
My PAUSE-Permissions
distribution contains the
PAUSE::Permissions
module that provides an interface to the 06perms.txt
file,
which is exported by PAUSE. The file tells you who has what permissions
for every module on CPAN. You can look up the permissions for
a specific module, and this will return an object that holds the
permissions information for the module.
When first creating PAUSE-Permissions
, I briefly considered
creating a module called something like Module::Metadata
.
But that's not a good idea, and instead it returns
an instance of
PAUSE::Permissions::Module.
Why should you put all your modules under one namespace?
Another example I came across recently: early versions of the
CORBA-IDL distribution
contained modules called BooleanType
, Enum
, Element
, Ellipsis
, etc.
Those are very generic top-level names, and someone might be surprised
to find that an Enum class is actually related to CORBA.
The more recent releases changed these to be CORBA::IDL::BooleanType
,
CORBA::IDL::Enum
, etc. It turns out that the Enum
module caused
conflict with the enum module that
I recently adopted, which meant I couldn't release it until
François removed Enum
from CPAN
and gave up his PAUSE permission for it.
In general you should try and keep one concept per distribution. If you really think that you should use a different namespace for one or more of the modules in your distribution, then maybe you should be thinking about a separate distribution for that module / those modules.
Given my example above, I briefly thought about a separate
general-purpose module for holding information about modules.
But there were already several such modules,
and to do what I wanted right would have been a lot of effort.
So much better, and easier for me,
to stay within my PAUSE::Permissions
namespace.
If you really think your dist should have multiple namespaces:
In the meantime, if you're desparate to release your dist to CPAN, keep everything under one namespace: you can always change it later, if you get agreement.
Of course, there are exceptions to every rule, and you can find distributions that break the guideline given here, sometimes for good reason. For example, the Moose distribution includes Class::MOP, which implements the meta object protocol that Moose is built on. Unfortunately the reverse dependency services are based on dists, so I can't tell whether there are other dists that use Class::MOP but don't use Moose. If there are, then I'd argue that perhaps Class::MOP should be spun out.
Toby gave a good example in his comment below: many dists contain one or more classes
in the Test::
namespace. But in that case, if your module is Foo::Bar
, then such
a class should probably be Test::Foo::Bar
.
For example the Perl-Critic
dist contains Test::Perl::Critic::Policy.