Question

Edit

I've prefixed the explanation here, for the benefit of anyone else confused by this issue. As @Ikegami explained,

  • VERSION_FROM indicates where the distribution's version comes from, if not in the top-level module;
  • PREREQ_PM indicates (optionally) the version of each required module

Often a distribution, with a version number, consists of several modules, each of which comes with its own version number, not the same as the distribution's number.

On the other end of the spectrum, a distribution consisting of a single module in a single file will not need to take advantage of VERSION_FROM.

However, for the middle case:

  • a distribution of several modules & programs which should have the same version number, and
  • there are enough files or programs where it is advantageous to put the version number into a single separate file

then, the hack described below may be of use to you.

Hope that helps somebody!

Original Question

Practically the first thing I see in ExtUtils::MakeMaker's POD is VERSION_FROM, which suggests that could, or maybe even should use it. However, even MakeMaker itself doesn't see the version of prerequisites (listed with PREREQ_PM) unless it is in the top-level module. That is, if I setup another module Bar that requires a particular version of Foo, where Foo defines its version somewhere other than Foo.pm, MakeMaker will reports the version of Foo as unknown.

Seems like such an obvious, and longstanding, bug that makes me wonder if I'm just misunderstanding or misusing it?

EDIT The question is: Why does MakeMaker encourage VERSION_FROM when it does not use it to get the version?

EDIT The following is a possibly questionable workaround, not the main question:

OTOH, the code in ExtUtils::MM_Unix that checks the version in no way looks anywhere that VERSION_FROM would have indicated. However, it does indicate an interesting workaround.

If Module Foo has in Makefile.PM:

WriteMakefile(
  NAME=>'Foo',
  VERSION_FROM => 'lib/Foo/Version.pm',
  ...

lib/Foo/Version.pm obviously has

use vars qw($VERSION);
$VERSION = '0.1';

and then in Foo.pm, you put:

$Foo::VERSION = do { use Foo::Version; $Foo::Version::VERSION; };

and everything works..... For now!

So, is it a bug in MakeMaker? and/or is my workaround tolerably sane (by Perl standards)?

thanks

Was it helpful?

Solution 2

"Works", in this context, would be that when trying to build the hypothetical package "Bar", that MakeMaker would realize that Foo has version 0.1.

VERSION_FROM specifies where to obtain the distribution's version. It doesn't set any module's version.

PREREQ_PM defines the list of modules and (in terms of their name and version) the distribution requires.

A module's version may be different than the version of the distribution in which it resides. The module Foo has no version, which is why requiring version 0.1 of module Foo is (correctly) failing.

OTHER TIPS

The $VERSION variable is obviously like any other variable, so you can set it in imaginative ways like:

$Foo::VERSION = do { use Foo::Version; $Foo::Version::VERSION; };

Or:

$Foo::VERSION = grep /[aeiou]/, 'a'..'z';   # version five

However, a lot of toolchain modules (including ExtUtils::MakeMaker) do not execute your file to find the version number. Instead they'll grep through it's lines and try to look for something that looks like a number being assigned to something that looks like a variable called $VERSION, and guess that that number is the module's version. That's not ideal of course, but that's the world we live in.

To let these tools work, you need to make sure to set your version number in a really easy way, a la:

$Foo::VERSION = '1.001';

If you have a lot of modules, and are worried about updating the version numbers on all of them simultaneously, then install Perl::Version which comes bundled with a script called perl-reversion that makes it really easy to update the version numbers in a bunch of modules in one go.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top