I’ve been looking at patterns of $VERSION definition in the wild. And, wow. There’s some crazy stuff out there.
Remember that the way PAUSE (and other tools) parse a $VERSION definition line is not by loading the module, but by extracting it as a standalone line and essentially running it through eval. PAUSE says this must work:
perl -MExtUtils::MakeMaker -le 'print MM->parse_version(shift)' path/to/file.pm
PAUSE actually does something more sophisticated and safe, but if parse_version works, so will PAUSE.
Keeping that in mind, listed below are some of the more surprising/amusing/horrifying things I’ve seen. Not all are broken, but even the ones that work are, well, unusual.
I’m not naming any names — and I’ll obscure them if it would be too revealing — but these are all from real .pm files in tarballs currently indexed on CPAN.
$VERSION = '';
$VERSION = '0.O1';
$VERSION = "0.01c";
$VERSION = VERSION;
$VERSION = '0.10E0';
our $VERSION = -722;
my $VERSION = '0.01';
$VERSION = 0xdeadbeef;
our $VERSION = '1.0-1';
$VERSION = 2006_08_16.1;
our $VERSION = '0.8.1-2';
$VERSION = $VERSION = "0.1";
$Foo::Bar::VERSION |= '2.6';
my $VERSION = 'OMG-04-05-01';
our $VERSION = '1.4.A8UG1gG';
our $VERSION = 'set-when-loading';
our $VERSION = '$Revision: 1.2 $';
our $VERSION = $Foo::Bar::VERISON;
our $VERSION=$Foo::VERSION; use Foo;
local $Other::Module::VERSION = 666;
$Foo::Bar::VERSION="1.23" unless $Foo::Bar::VERSION;
$Foo::Bar::VERSION='1.00' unless $INC{'Foo/Bar0.pm'};
$VERSION=eval 'use version;1' ? 'version'->new('0.33') : '0.33';
Some of these are so nuts that unless they are modified by a subsequent line into a standard version format, then a version check will throw an error on any recent perl:
# Foo.pm package Foo; our $VERSION = "1.2-trailing-junk";
$ perl -I. -we 'use Foo 0;' Invalid version format (non-numeric data) at -e line 1. BEGIN failed--compilation aborted at -e line 1.
Moral of this story: make sure your $VERSION definition parses cleanly on a line by itself and make sure it’s a valid version number. If you’re not sure, check it with the is_lax function from version.pm.