.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Perl::Critic::Policy::ValuesAndExpressions::RequireNumericVersion 3pm" .TH Perl::Critic::Policy::ValuesAndExpressions::RequireNumericVersion 3pm "2021-02-28" "perl v5.32.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Perl::Critic::Policy::ValuesAndExpressions::RequireNumericVersion \- $VERSION a plain number .SH "DESCRIPTION" .IX Header "DESCRIPTION" This policy is part of the \f(CW\*(C`Perl::Critic::Pulp\*(C'\fR add-on. It asks you to use a plain number in a module \f(CW$VERSION\fR so that Perl's builtin version works. .PP Any literal number is fine, or a string which is a number, .PP .Vb 3 \& $VERSION = 123; # ok \& $VERSION = \*(Aq1.5\*(Aq; # ok \& $VERSION = 1.200_001; # ok .Ve .PP For Perl 5.10 and higher the extra forms of the \f(CW\*(C`version\*(C'\fR module too, .PP .Vb 2 \& use 5.010; \& $VERSION = \*(Aq1.200_001\*(Aq; # ok for 5.10 up, version.pm .Ve .PP But a non-number string is not allowed, .PP .Vb 1 \& $VERSION = \*(Aq1.2alpha\*(Aq; # bad .Ve .PP 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 \*(L"bugs\*(R" theme (see \*(L"\s-1POLICY THEMES\*(R"\s0 in Perl::Critic). .PP .Vb 2 \& use Foo 1.0; \& Foo\->VERSION(1); .Ve .PP A plain number is also highly desirable so applications can do their own compares like .PP .Vb 1 \& if (Foo\->VERSION >= 1.234) { .Ve .PP In each case if \f(CW$VERSION\fR is not a number then it provokes warnings, and may end up appearing as a lesser version than intended. .PP .Vb 1 \& Argument "1.2.alpha" isn\*(Aqt numeric in subroutine entry .Ve .PP If you've loaded the \f(CW\*(C`version.pm\*(C'\fR module then a \f(CW$VERSION\fR not accepted by \&\f(CW\*(C`version.pm\*(C'\fR will in fact croak, which is an unpleasant variant behaviour. .PP .Vb 3 \& use version (); \& print "version ",Foo\->VERSION,"\en"; \& # croaks "Invalid version format ..." if $Foo::VERSION is bad .Ve .SS "Scripts" .IX Subsection "Scripts" This policy only looks at \f(CW$VERSION\fR in modules. \f(CW$VERSION\fR in a script can be anything since it won't normally be part of \f(CW\*(C`use\*(C'\fR checks etc. A script \f(CW$VERSION\fR is anything outside any \f(CW\*(C`package\*(C'\fR statement scope, or under an explicit \f(CW\*(C`package main\*(C'\fR. .PP .Vb 2 \& package main; \& $VERSION = \*(Aq1.5.prerelease\*(Aq; # ok, script \& \& $main::VERSION = \*(Aqblah\*(Aq; # ok, script \& $::VERSION = \*(Aqxyzzy\*(Aq; # ok, script .Ve .PP A fully-qualified package name is recognised as belonging to a module, .PP .Vb 1 \& $Foo::Bar::VERSION = \*(Aqxyzzy\*(Aq; # bad .Ve .SS "Underscores in Perl 5.8 and Earlier" .IX Subsection "Underscores in Perl 5.8 and Earlier" In Perl 5.8 and earlier a string like \*(L"1.200_333\*(R" is truncated to the numeric part, ie. 1.200, and can thus fail to satisfy .PP .Vb 2 \& $VERSION = \*(Aq1.222_333\*(Aq; # bad \& use Foo 1.222_331; # not satisfied by $VERSION=\*(Aqstring\*(Aq form .Ve .PP But an actual number literal with an \*(L"_\*(R" is allowed. Underscores in literals are stripped out (see perldata), but not in the automatic string to number conversion so a string like \f(CW\*(C`$VERSION = \*(Aq1.222_333\*(Aq\*(C'\fR provokes a warning and stops at 1.222. .PP .Vb 1 \& $VERSION = 1.222_333; # ok .Ve .PP On \s-1CPAN\s0 an underscore in a distribution version number is rated as a developer pre-release. But don't put it in module \f(CW$VERSION\fR strings due to the problems above. The suggestion is to include the underscore in the distribution filename but either omit it from the \f(CW$VERSION\fR or make it a number literal not a string, .PP .Vb 2 \& $VERSION = 1.002003; # ok \& $VERSION = 1.002_003; # ok, but not for VERSION_FROM .Ve .PP \&\f(CW\*(C`ExtUtils::MakeMaker\*(C'\fR \f(CW\*(C`VERSION_FROM\*(C'\fR will take the latter as its numeric value, ie. \*(L"1.002003\*(R" not \*(L"1.002_003\*(R" as the distribution version. For the latter you can either put an explicit \f(CW\*(C`VERSION\*(C'\fR in \fIMakefile.PL\fR .PP .Vb 2 \& use ExtUtils::MakeMaker; \& WriteMakefile (VERSION => \*(Aq1.002_003\*(Aq); .Ve .PP Or you can trick MakeMaker with a string plus \f(CW\*(C`eval\*(C'\fR, .PP .Vb 2 \& $VERSION = \*(Aq1.002_003\*(Aq; # ok evalled down \& $VERSION = eval $VERSION; .Ve .PP \&\f(CW\*(C`MakeMaker\*(C'\fR sees the string \*(L"1.002_003\*(R" but at runtime the \f(CW\*(C`eval\*(C'\fR crunches it down to a plain number 1.002003. \f(CW\*(C`RequireNumericVersion\*(C'\fR notices such an \f(CW\*(C`eval\*(C'\fR and anything in \f(CW$VERSION\fR. Something bizarre in \f(CW$VERSION\fR won't be noticed, but that's too unlikely to worry about. .ie n .SS """version"" module in Perl 5.10 up" .el .SS "\f(CWversion\fP module in Perl 5.10 up" .IX Subsection "version module in Perl 5.10 up" In Perl 5.10 \f(CW\*(C`use\*(C'\fR etc module version checks parse \f(CW$VERSION\fR with the \&\f(CW\*(C`version.pm\*(C'\fR module. This policy allows the \f(CW\*(C`version\*(C'\fR module forms if there's an explicit \f(CW\*(C`use 5.010\*(C'\fR or higher in the file. .PP .Vb 3 \& use 5.010; \& $VERSION = \*(Aq1.222_333\*(Aq; # ok for 5.10 \& $VERSION = \*(Aq1.2.3\*(Aq; # ok for 5.10 .Ve .PP But this is still undesirable, as an application check like .PP .Vb 1 \& if (Foo\->VERSION >= 1.234) { .Ve .PP gets the raw string from \f(CW$VERSION\fR and thus a non-numeric warning and truncation. Perhaps applications should let \f(CW\*(C`UNIVERSAL.pm\*(C'\fR do the work with say .PP .Vb 1 \& if (eval { Foo\->VERSION(1.234) }) { .Ve .PP or apply \f(CW\*(C`version\->new()\*(C'\fR to one of the args. Maybe another policy to not explicitly compare \f(CW$VERSION\fR, or perhaps an option to tighten this policy to require numbers even in 5.10? .SS "Exponential Format" .IX Subsection "Exponential Format" Exponential strings like \*(L"1e6\*(R" are disallowed .PP .Vb 1 \& $VERSION = \*(Aq2.125e6\*(Aq; # bad .Ve .PP Except with the \f(CW\*(C`eval\*(C'\fR trick as per above .PP .Vb 2 \& $VERSION = \*(Aq2.125e6\*(Aq; # ok \& $VERSION = eval $VERSION; .Ve .PP Exponential number literals are fine. .PP .Vb 1 \& $VERSION = 1e6; # ok .Ve .PP Exponential strings don't work in Perl 5.10 because they're not recognised by the \f(CW\*(C`version\*(C'\fR 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. .SS "Disabling" .IX Subsection "Disabling" If you don't care about this policy at all then you can disable from your \&\fI.perlcriticrc\fR in the usual way (see \*(L"\s-1CONFIGURATION\*(R"\s0 in Perl::Critic), .PP .Vb 1 \& [\-ValuesAndExpressions::RequireNumericVersion] .Ve .SS "Other Ways to Do It" .IX Subsection "Other Ways to Do It" 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. .PP .Vb 1 \& $VERSION = 123; .Ve .PP If you want sub-versions then increment by 100 or some such. Even a \&\s-1YYYYMMDD\s0 date is a possibility. .PP .Vb 1 \& $VERSION = 20110328; .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Perl::Critic::Pulp, Perl::Critic .PP Perl::Critic::Policy::Modules::RequireVersionVar, Perl::Critic::Policy::ValuesAndExpressions::ProhibitComplexVersion, Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion .PP Perl::Critic::Policy::ValuesAndExpressions::ProhibitVersionStrings, Perl::Critic::Policy::Modules::ProhibitUseQuotedVersion .SH "HOME PAGE" .IX Header "HOME PAGE" http://user42.tuxfamily.org/perl\-critic\-pulp/index.html .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2021 Kevin Ryde .PP Perl-Critic-Pulp is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. .PP Perl-Critic-Pulp is distributed in the hope that it will be useful, but \&\s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 See the \s-1GNU\s0 General Public License for more details. .PP You should have received a copy of the \s-1GNU\s0 General Public License along with Perl-Critic-Pulp. If not, see .