Perl::Critic::Policy::ValuesAndExpressions::RequireNumericVersion - $VERSION a plain number
This policy is part of the Perl::Critic::Pulp add-on. It asks you to use a plain number in a module $VERSION so that Perl's builtin version works.
Perl::Critic::Pulp
$VERSION
Any literal number is fine, or a string which is a number,
$VERSION = 123; # ok $VERSION = '1.5'; # ok $VERSION = 1.200_001; # ok
For Perl 5.10 and higher the extra forms of the version module too,
version
use 5.010; $VERSION = '1.200_001'; # ok for 5.10 up, version.pm
But a non-number string is not allowed,
$VERSION = '1.2alpha'; # bad
The idea of this requirement is that a plain number is needed for Perl's builtin module version checking like the following, and on that basis this policy is under the "bugs" theme (see "POLICY THEMES" in Perl::Critic).
use Foo 1.0; Foo->VERSION(1);
A plain number is also highly desirable so applications can do their own compares like
if (Foo->VERSION >= 1.234) {
In each case if $VERSION is not a number then it 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, which is an unpleasant variant behaviour.
version.pm
use version (); print "version ",Foo->VERSION,"\n"; # croaks "Invalid version format ..." if $Foo::VERSION is bad
This policy only looks at $VERSION in modules. $VERSION in a script can be anything since it won't normally be part of use checks etc. A script $VERSION is anything outside any package statement scope, or under an explicit package main.
use
package
package main
package main; $VERSION = '1.5.prerelease'; # ok, script $main::VERSION = 'blah'; # ok, script $::VERSION = 'xyzzy'; # ok, script
A fully-qualified package name is recognised as belonging to a module,
$Foo::Bar::VERSION = 'xyzzy'; # bad
In Perl 5.8 and earlier a string like "1.200_333" is truncated to the numeric part, ie. 1.200, and can thus fail to satisfy
$VERSION = '1.222_333'; # bad use Foo 1.222_331; # not satisfied by $VERSION='string' form
But an actual number literal with an "_" is allowed. Underscores in literals are stripped out (see perldata), but not in the automatic string to number conversion so a string like $VERSION = '1.222_333' provokes a warning and stops at 1.222.
$VERSION = '1.222_333'
$VERSION = 1.222_333; # ok
On CPAN an underscore in a distribution version number is rated as a developer pre-release. But don't put it in module $VERSION strings due to the problems above. The suggestion is to include the underscore in the distribution filename but either omit it from the $VERSION or make it a number literal not a string,
$VERSION = 1.002003; # ok $VERSION = 1.002_003; # ok, but not for VERSION_FROM
ExtUtils::MakeMaker VERSION_FROM will take the latter as its numeric value, ie. "1.002003" not "1.002_003" as the distribution version. For the latter you can either put an explicit VERSION in Makefile.PL
ExtUtils::MakeMaker
VERSION_FROM
VERSION
use ExtUtils::MakeMaker; WriteMakefile (VERSION => '1.002_003');
Or you can trick MakeMaker with a string plus eval,
eval
$VERSION = '1.002_003'; # ok evalled down $VERSION = eval $VERSION;
MakeMaker sees the string "1.002_003" but at runtime the eval crunches it down to a plain number 1.002003. RequireNumericVersion notices such an eval and anything in $VERSION. Something bizarre in $VERSION won't be noticed, but that's too unlikely to worry about.
MakeMaker
RequireNumericVersion
In Perl 5.10 use etc module version checks parse $VERSION with the version.pm module. This policy allows the version module forms if there's an explicit use 5.010 or higher in the file.
use 5.010
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
gets the raw string from $VERSION and thus a non-numeric warning and truncation. Perhaps applications should let UNIVERSAL.pm do the work with say
UNIVERSAL.pm
if (eval { Foo->VERSION(1.234) }) {
or apply version->new() to one of the args. Maybe another policy to not explicitly compare $VERSION, or perhaps an option to tighten this policy to require numbers even in 5.10?
version->new()
Exponential strings like "1e6" are disallowed
$VERSION = '2.125e6'; # bad
Except with the eval trick as per above
$VERSION = '2.125e6'; # ok $VERSION = eval $VERSION;
Exponential number literals are fine.
$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 in the interests of maximum compatibility this policy treats such a string as non-numeric. Exponentials in versions should be unusual anyway.
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]
The version number system with underscores, multi-dots, v-nums, etc is diabolical mess, and each new addition to it just seems to make it worse. Even the original floating point in version checks is asking for rounding error trouble, though normally fine in practice. A radical simplification is to just use integer version numbers.
$VERSION = 123;
If you want sub-versions then increment by 100 or some such. Even a YYYYMMDD date is a possibility.
$VERSION = 20110328;
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
http://user42.tuxfamily.org/perl-critic-pulp/index.html
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2021 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/>.
To install Perl::Critic::Pulp, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Perl::Critic::Pulp
CPAN shell
perl -MCPAN -e shell install Perl::Critic::Pulp
For more information on module installation, please visit the detailed CPAN module installation guide.