NAME
Perl::Critic::Policy::ValuesAndExpressions::RequireNumericVersion - $VERSION a plain number
DESCRIPTION
This policy is part of the Perl::Critic::Pulp
addon. It ask you to use a plain number in module $VERSION
so that version checking within a program will work properly. This policy is under the bugs
theme (see "POLICY THEMES" in Perl::Critic).
Any literal number is fine, or a string which is a number, and for Perl 5.10 up the extra forms of the version
module too, but a non-numeric string is not allowed.
$VERSION = '1.2alpha'; # bad
$VERSION = 123; # ok
$VERSION = '1.5'; # ok
$VERSION = 1.200_001; # ok
$VERSION = '1.200_001'; # ok for 5.10 up
A number is needed for version checking like
use Foo 1.0; # Perl's module checking
Foo->VERSION(1); # app runtime check
and it's highly desirable so applications can do compares like
if (Foo->VERSION >= 1.234) {
In each case a non-numeric string in $VERSION
provokes warnings, and may end up appearing as a lesser version than intended.
Argument "1.2.alpha" isn't numeric in subroutine entry
If you've loaded the version.pm
module, then a $VERSION
not accepted by version.pm
will in fact croak
use version;
print "version ",Foo->VERSION,"\n";
# croaks "Invalid version format ..." if $Foo::VERSION is bad
Scripts
This policy only looks at $VERSION
in modules. $VERSION
in a script can be anything, as it won't normally have a use
checks etc. A script $VERSION
is anything outside any package
statement, or under an explicit package main
.
package main;
$VERSION = '1.5.prerelease'; # ok, script
Underscores in Perl 5.8 and Earlier
In Perl 5.8 and earlier a string like "1.200_333" is truncated to the numeric part, ie. 1.200, and thus can fail to satisfy
$VERSION = '1.222_333'; # bad
$VERSION = 1.222_333; # ok
use Foo 1.222_331; # unsatisfied by $VERSION='string' form
A number literal with an "_" is allowed. Underscores in literals are stripped out, as described in perldata, but not in the automatic string to number conversion and a string like $VERSION = '1.222_333'
provokes a warning and stops at 1.222.
On CPAN an underscore in a distribution version number means a developer pre-release. But avoid that in module $VERSION
strings for the problems above. The suggestion is to either omit the underscore or make it a number literal not a string,
$VERSION = 1.002003; # ok
$VERSION = 1.002_003; # ok
If using ExtUtils::MakeMaker
then it may be necessary to put an explicit VERSION
in Makefile.PL to get the underscore in the dist name, rather than VERSION_FROM
a module file, since VERSION_FROM
takes both the above to be 1.002003.
version
module in Perl 5.10
In Perl 5.10 the use
etc module version checks parse $VERSION
with the version.pm
module. This policy allows version
module forms if there's an explicit use 5.010
or higher in the file.
use 5.010;
$VERSION = '1.222_333'; # ok for 5.10
$VERSION = '1.2.3'; # ok for 5.10
But this is still undesirable, as an application check like
if (Foo->VERSION >= 1.234) {
gets the raw string from $VERSION
and thus a non-numeric warning and truncation. Perhaps applications should let UNIVERSAL.pm
do the check with say
if (eval { Foo->VERSION(1.234) }) {
or apply version->new()
to one of the args. (Could have another policy to not explicitly compare $VERSION
, or perhaps an option to tighten this policy to require numbers even in 5.10?)
Exponential Format
Exponential format strings like "1e6" are disallowed. Exponential number literals are fine.
$VERSION = '2.125e6'; # bad
$VERSION = 1e6; # ok
Exponential strings don't work in Perl 5.10 because they're not recognised by the version
module (v0.82). They're fine in Perl 5.8 and earlier, but this policy treats such a string as non-numeric in the interests of compatibility with later Perl. Exponentials in versions should be unusual anyway.
Disabling
If you don't care about this policy at all then you can disable from your .perlcriticrc in the usual way (see "CONFIGURATION" in Perl::Critic),
[-ValuesAndExpressions::RequireNumericVersion]
Other Ways to Do It
All the version number stuff with underscores, multi-dots, v-nums, etc is a diabolical mess. And floating point in version checks is asking for rounding error trouble (though fine in practice). A radical simplification is to just use integer version numbers.
$VERSION = 42;
If you want sub-versions then increment by 100 say. Even a YYYYMMDD date is a possibility.
$VERSION = 20110328;
SEE ALSO
Perl::Critic::Pulp, Perl::Critic
Perl::Critic::Policy::Modules::RequireVersionVar, Perl::Critic::Policy::ValuesAndExpressions::ProhibitComplexVersion, Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion
Perl::Critic::Policy::ValuesAndExpressions::ProhibitVersionStrings, Perl::Critic::Policy::Modules::ProhibitUseQuotedVersion
HOME PAGE
http://user42.tuxfamily.org/perl-critic-pulp/index.html
COPYRIGHT
Copyright 2011 Kevin Ryde
Perl-Critic-Pulp is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
Perl-Critic-Pulp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Perl-Critic-Pulp. If not, see <http://www.gnu.org/licenses/>.