When using someone else's module in our CPAN modules, most of us don't bother to specify a minimum version of that module. If no-one else is using your module you can get away with that. But as your distribution moves up the CPAN River, you should start paying attention, and specify minimum versions both in the code and your distribution's metadata.

My July assignment in the CPAN Pull Request Challenge was STEVAN's Path::Router. But FELLIOTT had already submitted a PR to switch it from Moose to Moo. Turning the tables on me, Stevan ended up giving me commit rights to his repo, so I could merge Fitz's PR. One of the things he suggested was making sure it required version 2 of Moo, since that addressed the concerns people had over fatal warnings. I ended up spending a lot of time looking at the Changes file for all the dists used by Path::Router , and thinking about minimum versions.

Works for me!

When using someone else's module in your code, I suspect most of us often just write:

use Foobar;

And in the prerequisites you'll usually see:

Foobar => 0

This effectively says "it doesn't matter what version", but what you're really saying is "it works with the version of Foobar I have installed here, on my operating system and my version of Perl". Sometimes you'll see someone specifying a minimum version, but my experience of that to date has been that it usually happens once you've been bitten. Or, I suspect, if you're cargo culting something you saw in someone else's code.

If my dists aren't being used by any others, I can probably get away with this. But as other dists start relying on mine, I think I owe it to them to start paying more attention to versions of the dists that I'm using. Other people are going to be on different operating systems from me, using different versions of Perl, and with random versions of other CPAN dists installed.

What version should I specify?

The trouble is, it's not always obvious what version you should require when you look at a dist, especially for larger dists. If you're using a function or method that was introduced in a particular release, then that's a good start point.

But then you should work through the Changes file and see whether there are any subsequent bug fixes or changes that you're relying on. If you're not sure, you could consider asking the author, or asking on IRC. You could also look at the dist's CPAN Testers results: if you see that all releases are green beyond a certain version, that's another useful data point.

I'm still trying to work out what the right approach is, but for the moment my thought is to work through the Changes file for each dist:

Start with the most recent release and work backwards until you find either a feature you're relying on, or a bugfix.

If you're sure the fixed bug doesn't affect your dist, keep working backwards. Otherwise stop there and specify that as the minimum version.

I realise that is a pain, but I've had a thought about that, which I'll write up separately.

Perl is a upriver dependency too

The version of Perl your dist requires depends on (a) the language features that you use, possibly (b) the version that you specify as a minimum version, and (c) the highest version of Perl required by your upriver dependencies.

It's not always easy to identify what version of Perl is required by your upriver dists. So you should make it easy for your downriver dists:

Document it in the code, eg with use 5.010; if you require Perl 5.10.0 or later.

if you require Perl 5.10.0 or later. Make sure your dist's metadata gives the minimum Perl version.

If you ever change what version of Perl your dist requires, document that in the Changes file, so people relying on your dist know all the implications of a particular version.

Versions of modules and distributions

When specifying a version with use , remember that you're giving the version of the module, not the distribution that contains it. These are often the same, but not always.

For me this is a good reason to follow these guidelines:

All modules should have a version number.

A distribution's version number should match the version of all modules it contains.

Dist::Zilla makes it easy to do this.

For example, consider the Mojo::Loader module which is part of the Mojolicious distribution. If you look at the source of Mojo::Loader, you'll see it doesn't have a $VERSION number (intentionally).

Release 6.12 of Mojolicious added the find_packages function to Mojo::Loader . If you're going to use this in your code, you should write:

use Mojo::Loader 6.12 qw/ find_packages /;

But you can't, because Mojo::Loader doesn't have a $VERSION .

Conclusion

I'm still trying to work out what the right thing to do is, but for the moment my new model is: when (considering) using a module:

Read its Changes file, and if you can't work out which version to rely on, start at the most recent and work back until you hit the most recent bugfix, and consider requiring that version.

Look at what version of perl it requires.

Talk to the author if you're not sure.

Another option (see ETHER's comments below):

Set the Perl version to 5.006 and module versions to 0, then release your module.

Watch CPAN Testers for failures, and work out whether any of them can be addressed by setting minimum required versions for any modules or Perl.

The downside with this approach is that you might not always be able to work out whether a failure is down to a specific version of one module you're using. If you're adding a new module dependency to an existing module, then this sort of experimentation should be done with a developer release. You won't see any knock-on effects on your downriver dependencies with the developer release though.

What cases have I missed?

Please enable JavaScript to view the comments powered by Disqus.

Disqus