NAME
Version::Dotted - Bump a dotted version, check if version is trial
VERSION
Version v0.0.1, released on 2017-01-04 21:35 UTC.
WHAT?
Version::Dotted
and its subclasses are authoring time extensions to core version
class: they complement version
with bump operation and implement alternative trial version criteria.
This is Version::Dotted
module documentation. Read it first because it contains many relevant details, and use one of subclasses.
General topics like getting source, building, installing, bug reporting and some others are covered in the README.
SYNOPSIS
use Version::Dotted; # import nothing
use Version::Dotted 'qv'; # import qv
# Construct:
$v = Version::Dotted->new( v1.2.3 ); # same as qv( v1.2.3 )
$v = qv( v1.2.3 ); # v1.2.3
$v = qv( 'v1.2.0' ); # v1.2 (trailing zero parts ignored)
$v = qv( 'v1' ); # v1
# Access parts:
@int = $v->parts; # Get all parts.
$int = $v->part( $i ); # Get i-th part (zero-based).
# Bump the version:
$v->bump( $i ); # Bump i-th part
# and drop all parts behind i-th.
# Determine release status:
$bool = $v->is_trial;
# Stringify:
$str = $v->stringify; # "v1.2.3"
$str = "$v"; # ditto
# Compare:
$bool = $v >= v1.2.3;
$bool = $v <=> 'v1.2.3';
DESCRIPTION
Purpose
Version::Dotted
is authoring time extension to version
. It means Version::Dotted
and its subclasses are intended to be used in authoring tools (like Dist::Zilla
plugins) when author prepares a distribution. Version::Dotted
and its subclasses serve for two purposes:
To bump a dotted version.
To implement alternative trial version criteria not depending on underscore character.
Version::Dotted
is not required to build, install, and use module(s) from prebuilt distribution, core version
works at these stages.
See also "WHY?".
Types of Versions
Historically, two types of version numbers are used in Perl: decimal and dotted.
Version::Dotted
handles only dotted versions, no support for decimal versions is provided intentionally.
Bumping
"Bumping" means incrementing a version part by one and dropping all the parts behind the incremented. For example, bumping the third part of v1.2.3
gives v1.2.4
, bumping the second part of v1.2.4
gives v1.3
(the third part is dropped).
Trial Versions
Firstly, Version::Dotted
prefers "trial" term to "alpha" (see "Non-Stable Releases").
Secondly, trial versions are not denoted by underscore character anymore (see "WHY?"). Version::Dotted
defines interface, exact criteria are implemented in subclasses.
Parent(s)
Version::Dotted
is heavily influenced by Perl::Version
, but Version::Dotted
is not a subclass of Perl::Version
.
Version::Dotted
it is a subclass of version
. Version::Dotted
extends version
— Version::Dotted
objects are modifiable, but it also narrows version
— Version::Dotted
creates only dotted (aka dotted-decimal) version objects.
Error Reporting
The class reports error by warnings::warnif
. It gives flexibility to the caller: warning may be either suppressed
no warnings 'Version::Dotted';
or made fatal:
use warnings FATAL => 'Version::Dotted';
EXPORT
The module exports nothing by default.
The module installs qv
function (not a method) into caller namespace by explicit request:
use Version::Dotted 'qv';
If caller module already has qv
function, warning is issued and function is redefined.
Note: version
exports qv
by default, if caller package does not have qv
function yet.
The module (unlike to version
) does not play any tricks with importer's VERSION
and/or UNIVERSAL::VERSION
.
CLASS ATTRIBUTES
min_len
Minimal number of parts, read-only.
$int = Version::Dotted->min_len; # == 1
Objects are maintained to have at least minimal number of parts. In Version::Dotted
minimal number of parts is 1, subclasses may raise the bar.
CLASS METHODS
new
Constructs a new version object.
$obj = Version::Dotted->new( $arg );
The constructor accepts one argument and creates dotted version object. An argument can be either integer number (1
), floating point number (1.2
), v-string (v1.2
), or string (with or without leading v: '1.2'
, 'v1.2'
), or version
object. Trailing zero parts may be stripped (if number of parts exceeds required minimum), leading zeros in parts are insignificant:
Version::Dotted->new( 1.2.0 ) == Version::Dotted->new( v1.2 );
Version::Dotted->new( 1.002 ) == Version::Dotted->new( v1.2 );
However, to avoid surprises (see "Leading Zeros" and "Trailing Zeros") it is better to stick to using v-strings or strings, using numbers is not recommended (and may be prohibited in future).
parse
Prints warning "Method 'parse' is not supported" and returns undef
.
OBJECT METHODS
parts
Returns all parts of the version.
@int = $v->parts; # Get all parts.
In scalar context it gives number of parts in the version object:
$int = $v->parts; # Get number of parts.
part
Returns i-th part of the version.
$int = $v->part( $i ); # Get i-th part.
If index is larger than actual number of version parts minus one, undef
is returned.
Negative part index causes warning but works like index to regular Perl array: -1
is index of the last version part, -2
— second last, etc.
bump
Bumps i-th version part.
$v->bump( $i );
"Bumping" means incrementing i-th version part by one and dropping all the parts behind i-th:
$v = qv( v1.2.3 ); # $v == v1.2.3
$v->bump( 3 ); # $v == v1.2.3.1
$v->bump( 2 ); # $v == v1.2.4
$v->bump( 1 ); # $v == v1.3
$v->bump( 0 ); # $v == v2
If index is larger than actual number of version parts, missed parts are autovivified:
$v->bump( 5 ); # $v == v2.0.0.0.0.1
Negative part index causes warning but works.
The method returns reference to version object:
$v->bump( 2 )->stringify;
is_trial
Returns true in case of trial version, and false otherwise.
$bool = $v->is_trial;
This method always returns false, but descendants will likely redefine the method.
See also "Non-Stable Releases".
is_alpha
The method does the same as is_trial
but prints a warning.
stringify
Returns version string with leading 'v' character.
$str = $v->stringify;
See also "Stringification".
normal
The same as stringify
.
$str = $v->normal;
See also "Stringification".
numify
Prints warning "Method 'numify' is not supported" and returns undef
.
See also "Stringification".
FUNCTIONS
qv
Shortcut for Version::Dotted->new
.
$v = qv( $arg ); # same as $v = Version::Dotted->new( $arg );
(If the function is imported from Version::Dotted
subclass, it would be shortcut for Version::Dotted::Subclass->new
.)
The function is prototyped. It takes one scalar argument:
( $v, $w ) = qv v1.2.3, v1.2.3;
$v
will be a Dotted::Version
object, $w
will be a v-string. (version
's qv
grabs entire list but uses only the first argument, $w
will be undefined.)
Note: There is no function qv
in Version::Dotted
package, the function is installed into importer package by explicit request, see "EXPORT".
OPERATORS
<=>
Compares two versions.
$v <=> $other;
The operator is inherited from parent's class (see "How to compare version objects" in version). However, there is a subtle difference: if $other
is not a version object, it converted to a version object using new
(not parent's parse
).
Other comparison operators (e. g. <
, >
, <=
, etc) are created by Perl.
cmp
The same as <=>
.
""
Returns version string.
$str = "$v";
The same as stringify
.
CAVEATS
Leading Zeros
Leading zeros in parts are insignificant:
qv( v01.02.03 ) == v1.2.3;
qv( 1.002 ) == v1.2;
However, Perl interprets numbers with leading zero as octal, so be aware of:
qv( 010 ) == v8; # 010 == 8
qv( 010.011 ) == v89; # 010.011 eq 8 . 9 eq "89"
To avoid surprises stick to using v-strings or strings:
qv( v010 ) == v10;
qv( v010.011 ) == v10.10;
qv( 'v010.011' ) == v10.10;
Trailing Zeros
Perl ignores trailing zeros in floating point numbers:
1.200 == 1.2;
so
qv( 1.200 ) == v1.2; # not v1.200
To avoid such surprises stick to using v-strings or strings:
qv( v1.200 ) == v1.200;
qv( '1.200' ) == v1.200;
NOTES
Stringification
The parent class version
works with dotted and decimal versions and has three stringification methods:
$v->stringify; # as close to the original representatiion as possible
$v->numify; # (convert to) decimal version
$v->normal; # (convert to) dotted version with leading 'v'
normal
and numify
are used to convert a version to specified form, dotted or decimal respectively, regardless of its actual type:
version->parse( 1.003010 )->normal; # eq "v1.3.10"
version->declare( v1.3.10 )->numify; # eq "1.003010"
Version::Dotted
works with dotted versions only. normal
returns dotted version string with leading 'v' character (like parent does), stringify
does exactly the same, numify
is not supported:
$v->normal; # dotted version with leading 'v'
$v->stringify; # same as normal
$v->numify; # prints warning & returns undef
Practically it means Version::Dotted
has only one stringification method. Since there is no place for conversion, stringify
is the preferred name for it.
Using version
version
is an Perl core module. It serves for two purposes:
Declare package version.
version
module can be used either explicitly (works for any Perl version):package Assa; use version 0.77; our $VERSION = version->declare( 'v1.2.3' );
or implicitly (works for Perl 5.12.0 or later):
package Assa v1.2.3;
In the second case Perl automatically assigns
$VERSION
variable an object ofversion
class.Compare package versions:
version->parse( $Assa::VERSION ) >= 'v1.2.3';
Decimal Versions
Decimal version is just a floating-point number. In Perl decimal version can be represented by floating-point number, string, or version
object:
0.003010 # floating-point number
'0.003010' # string
version->parse( '0.003010' ) # version object
Floating-point numbers can be compared, but lose trailing zeros. Strings do not lose trailing zeros, but string comparison operators are not suitable for comparing versions. version
objects does not lose trailing zeros, can be easily compared, but cannot be modified.
See also: "Decimal Versions" in version::Internals.
Dotted Versions
Dotted (aka dotted-decimal) version is a series of parts joined with dots, each part is a cardinal (non-negative) integer. In Perl dotted versions can be represented by v-strings, strings, or version
objects:
v0.10.3 # v-string
'v0.10.3' # string
version->declare( 'v0.10.3' ) # version object
V-strings can be easily compared (by cmp
, eq
and other string comparison operators), but are not suitable for printing. Strings can be easily printed but string comparison operators are not suitable for comparing versions. version
objects can be easily compared and printed, but cannot be modified. (Version::Dotted
objects can be.)
Leading 'v' character is optional: in strings — always, in v-strings — if there are two or more dots. However, using 'v' character is recommended for clarity and readability.
See also: "Dotted-Decimal Versions" in version::Internals.
Conversion Rules
To convert a decimal version to dotted one: (1) insert dot after each third digit in fractional part, and then (2) strip leading zeros in every part:
1.003010 -(1)-> 1.003.010 -(2)-> 1.3.10
Obviously any possible decimal version can be conversed to corresponding dotted version.
To convert a dotted version to decimal one: (1) prepend each part (except the first) with leading zeros to have exactly 3 digits in each part, and then (2) strip all the dots except the first:
1.3.10 -(1)-> 1.003.010 -(2)-> 1.003010
Not all dotted version can be converted to corresponding decimal one. First, all parts (except the first) of a dotted version must comprise not more than 3 digits. Second, dotted version should not contain too many parts due to limited precision of floating-point numbers.
Non-Stable Releases
Perl terminology in this area is not well-defined and not consistently used:
The
version
module declares any version with underscore character (e. g.'v1.2.3_4'
) to be an "alpha" version.version::Internals
refers to CPAN convention "to note unstable releases with an underscore in the version string".In turn,
CPAN::Meta::Spec
defines release status as one of:stable
,testing
, andunstable
. Word "alpha" is used in the description ofunstable
release, whiletesting
release is described as "beta". There is also requirement thatstable
release version should not contain underscore. (There is no requirement thatunstanble
andtesting
releases should contain underscore.)pause.perl.org site has section named "Developer Releases" which is about releasing "code for testing". Such releases should either have version with underscore or "-TRIAL" suffix.
meta::cpan site in the list of module releases shows "DEV" (which likely means "developer release") after versions containing underscore.
dzil
tool has--trial
command line option to build a "release that PAUSE will not index".
"Alpha" term used by version
module (and some others) is a bad choice because it has strong association with "beta" and "release candidate" terms, which do not have any support by version
.
"Trial" term sounds more neutral and generic: a trial release could be either "alpha", "beta", "release candidate", "unstable", "testing", or "developer release".
Underscores
TODO
WHY?
version
is an official Perl module for declare and compare versions, it is recommended by Task::Kensho
and used by Perl itself (package Assa v1.2.3;
automatically assigns $VERSION
variable an object of version
class). Unfortunately, the module does not provide any method to bump a version.
Perl::Version
is another module recommended by Task::Kensho
. This module provides method(s) to bump a version, e. g.:
my $v = Perl::Version->new( 'v1.2.3' );
$v->inc_alpha;
"$v"; # eq 'v1.2.3_01'
I used such code with no problem… until version
0.9913. version
0.9913 changed interpretation of underscore character: before 'v1.2.3_01'
was interpreted as 'v1.2.3.1'
(+ trial flag, of course), starting from 0.9913 it is interpreted as 'v1.2.301'
(+ trial flag).
I believe there were good reasons for this change (e. g. current version
behavior matches Perl behavior and so reduces the mess), but this change breaks Perl::Version
as well as my code because
version->parse( 'v1.2.3_01' ) < 'v1.2.4'
was true before, is false now.
Thus, Perl::Version
is broken and it is not clear when and how it will be fixed. But
I want a method to bump a version, and want it now.
I want a method to represent trial versions, and want it is compatible with
version
either pre-0.9913 or post-0.9912 (i. e. >= 0.77).I want these methods to work with dotted versions, decimal versions are out of my interest.
(BTW: Requirement #2 effectively means that new method should not rely on underscores.)
Version::Dotted
fulfills these requirements.
SEE ALSO
- version
-
Parent class. It provides most of functionality, can work with decimal versions, but does not provide any modifiers. Release status depends on presence of underscore character in version.
- Perl::Version
-
An alternative to
version
. It works with both decimal and dotted versions, provides modification operations. Release status depends on presence of underscore character in version. - Version::Next
-
It provides authoring time subroutine to "increment module version numbers simply and correctly", works with both dotted and decimal versions, but it "no longer supports dotted-decimals with alpha elements".
- SemVer
-
It implements Semantic Versioning 1.0.0 with no changes (?).
SemVer
allows alphanumeric pre-release versions like'1.2.3-alpha1'
and orders them properly: 1.2.3-alpha < 1.2.3-beta < 1.2.3. However,SemVer
is not authoring time tool, it should be used in runtime also to provide correct ordering:version
does not recognize properly pre-release alphanumeric versions. - Version::Dotted::Semantic
-
Subclass implementing adaptation of Semantic Versioning, part of this distribution.
- Version::Dotted::Odd
-
Subclass implementing odd/even versioning scheme, part of this distribution.
AUTHOR
Van de Bugger <van.de.bugger@gmail.com>
COPYRIGHT AND LICENSE
Copyright (C) 2017 Van de Bugger
License GPLv3+: The GNU General Public License version 3 or later <http://www.gnu.org/licenses/gpl-3.0.txt>.
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.