views:

119

answers:

3

I thought I knew how to declare version numbers for modules. But after reading the article "$VERSION Confusion" at Modern Perl Books, a Modern Perl Blog; I'm now more confused than I started. (Ignorance was indeed bliss.) Not that I have hangups about "perfect" code but I'm just really curious why such a trivial matter apparently has no definitive answer for such a mature language.

Hope the SO community can find a definitive answer to this question as there are better things for Perl hackers to do than argue about different ways to declare version numbers.

+7  A: 

use Module VERSION

If the VERSION argument is present between Module and LIST, then the use will call the VERSION method in class Module with the given version as an argument. The default VERSION method, inherited from the UNIVERSAL class, croaks if the given version is larger than the value of the variable $Module::VERSION.

That makes for a straightforward pattern:

package MyModule;

our $VERSION = 1.23;

# ...

1;
Greg Bacon
I've been using 'our' since it was introduced.
GeneQ
+5  A: 

Most of your confusion is, I suspect, due to the page you linked advocating 1.2.3 style version "numbers". These are not fully supported throughout all the toolchain (regardless of what others may say) and should not be used. They offer no advantage over a simple numeric version, since they must for compatibility be treated as just a number in many places (e.g. 1.2.3 is treated as 1.002003). Oh, except that they are "cool". And maybe "elegant". And obnoxious.

The correct way to declare a version number is simple, unless you have an XS component or a alpha/beta indicator (_ in the version number), since then some things need to see a version string and some things a version number. Then it gets more complicated. perlmodstyle provides the correct incantation:

If you want to release a 'beta' or 'alpha' version of a module but don't want CPAN.pm to list it as most recent use an '_' after the regular version number followed by at least 2 digits, eg. 1.20_01. If you do this, the following idiom is recommended:

$VERSION = "1.12_01";
$XS_VERSION = $VERSION; # only needed if you have XS code
$VERSION = eval $VERSION;

(This assumes $VERSION and $XS_VERSION have already been declared; if not, simply add our to the first two lines.)

ysth
+1 for mentioning the eval idiom. You may want to leave this in all the time, so you don't forget to put it in when it's needed.
hobbs
Another way to handle alpha versions is to append the string `-TRIAL` to the _distribution's_ version number (not the module). e.g., CPAN will list `Foo-Bar-1.90-TRIAL.tar.gz` (containing Foo::Bar 1.90) as a development release, just as if it contained an underscore. Dist::Zilla makes it easy to make such a trial release.
cjm
+4  A: 

My position is keep it simple. Declare your version as a string containing a floating point number. Leave the multiple-decimal stuff for Perl's version numbers and Perl 6.

If your module requires Perl 5.6.0 or later:

our $VERSION = '1.02';

Or, if you need to remain compatible with Perl 5.005 or older:

use vars '$VERSION';
$VERSION = '1.02';

Some additional points:

  1. Always use the same number of digits after the decimal point. Some (non-Perl) packaging tools think version 1.11 comes after 1.9 but before 1.90. If you need to change the number of digits you use, increment the major version number at the same time.

  2. Always declare the version as a string. This keeps trailing zeros from disappearing. (See point 1.)

  3. If you want to make an unstable (e.g. alpha or beta) release, append the string -TRIAL to the distribution's version number (e.g. upload Foo-Bar-1.90-TRIAL.tar.gz containing Foo::Bar 1.90). This tells CPAN to list it as a development release, just as if it contained an underscore. Dist::Zilla makes it easy to make trial releases.

A string containing a floating point number will work with all versions of Perl, all versions of MakeMaker & Module::Build, and all Linux distributions I'm aware of.

cjm
Note: If you're currently using multiple-decimal versions, **do not** switch to a floating point version unless you increment the major version number at the same time (e.g., it's safe to go from 4.3.2 to '5.00', but not to '4.40').
cjm
Correction: pretty much everything in the world besides Perl thinks that 1.11 comes after 1.9 :)
hobbs