NAME
Changes::Version - Version string object class
SYNOPSIS
use Changes::Version;
my $v = Changes::Version->new(
major => 1,
minor => 2,
patch => 3,
alpha => 4,
qv => 1,
debug => 2,
);
# or
my $v = Changes::Version->new( 'v0.1.2_3' );
# or
my $v = Changes::Version->new( 'v0.1.2_3', alpha => 4 );
# or
my $v = Changes::Version->new( 'v0.1.2_3', { alpha => 4 } );
# or
my $v = Changes::Version->new( major => 0, minor => 1, patch => 2, alpha => 3, qv => 1 );
# or
my $v = Changes::Version->new({ major => 0, minor => 1, patch => 2, alpha => 3, qv => 1 });
die( Changes::Version->error ) if( !defined( $v ) );
my $v = Changes::Version->parse( 'v1.2.3_4' );
die( Changes::Version->error ) if( !defined( $v ) );
my $type = $v->type;
$v->type( 'decimal' );
$v->padded(0);
$v->pretty(1);
$v->type( 'dotted' );
$v++;
# Updating 'minor'
say "$v"; # v1.3.0
$v += 2;
$v->default_frag( 'major' );
$v++;
say "$v"; # v2.0.0
$v->inc_patch;
say $v->is_alpha; # false
say $v->numify; # returns new Changes::Version object
say $v->normal; # returns new Changes::Version object
say $v->as_string; # same as say "$v";
# 5.0.6_2
say $v->format( "%R%d%A" );
VERSION
v0.2.2
DESCRIPTION
This class represents a software version based on perl's definition and providing for perl recommended dotted decimal
and also decimal
types. In the future, this will be expanded to other non-perl version formats.
It allows for parsing and manipulation of version objects.
CONSTRUCTOR
new
Provided with an optional version string and an optional hash or hash reference of options and this will instantiate a new Changes::Version object.
If an error occurs, it will return an error, so alway check for the definedness of the returned value.
my $v = Changes::Version->new(
major => 1,
minor => 2,
patch => 3,
alpha => 4,
);
die( Changes::Version->error ) if( !defined( $v ) );
Note that if you do:
my $v = Changes::Version->new( ... ) || die( Changes::Version->error );
would be dangerous, because you would be assessing the return version object in a boolean context that could return false if the version was 0
.
It supports the following options that can also be accessed or changed with their corresponding method.
alpha
Specifies the alpha fragment integer of the version. See "alpha" for more information.
my $v = Changes::Version->new( major => 1, minor => 2, patch => 3, alpha => 4, ); my $alpha = $v->alpha; # 4 $v->alpha(7); say "$v"; # v1.2.3_7
beta
Specifies the beta fragment integer of the version. See "beta" for more information.
Currently unused and reserved for future release.
compat
Boolean. When enabled, this will ensure the version formatting is strictly compliant with the version module. Default to false.
default_frag
Specifies the fragment name or integer value used by overloaded operations.
my $v = Changes::Version->new( 'v1.2.3_4' ); my $default = $v->default_frag; # By default 'minor' $v->default_frag( 'major' ); $v++; # Version is now v2.2.3_4
extra
Specifies the array reference of version fragments beyond
patch
my $v = Changes::Version->new( major => 1, minor => 2, patch => 3, alpha => 12, extra => [qw( 4 5 6 7 )], ); say "$v"; # v1.2.3.4.5.6.7_12 my $a = $v->extra; # contains 4, 5, 6, 7
major
Specifies the
major
fragment of the version string.my $v = Changes::Version->new( major => 1, minor => 2, patch => 3, alpha => 4, ); my $major = $v->major; # 1 say "$v"; # v1.2.3_4 $v->major(3); say "$v"; # v3.0.0
minor
Specifies the
minor
fragment of the version string.my $v = Changes::Version->new( major => 1, minor => 2, patch => 3, alpha => 4, ); my $minor = $v->minor; # 2 say "$v"; # v1.2.3_4 $v->minor(3); say "$v"; # v1.3.0
original
Specifies an original version string. This is normally set by "parse" and used by "as_string" to bypass any formatting when nothing has been changed.
padded
Specifies whether version string of type decimal should be zero padded or not. Default to true.
my $v = Change::Version->new( major => 1, minor => 20, patch => 300, type => 'decimal', ); say "$v"; # 1.020300 $v->padded(0); say "$v"; # 1.0203
patch
Specifies the
patch
fragment of the version string.my $v = Changes::Version->new( major => 1, minor => 2, patch => 3, alpha => 4, ); my $patch = $v->patch; # 3 say "$v"; # v1.2.3_4 $v->patch(7); say "$v"; # v1.3.7
pretty
Specifies whether version string of type
decimal
should be formatted with an underscore (_
) separating thousands in the fraction part.my $v = Change::Version->new( major => 1, minor => 20, patch => 300, type => 'decimal', pretty => 1, ); say "$v"; # 1.020_300 $v->pretty(0); say "$v"; # 1.020300
qv
Specifies whether version string of type
dotted
should be formatted with the prefixv
. Defaults to true.my $v = Changes::Version->new( major => 1, minor => 2, patch => 3, alpha => 4, ); say "$v"; # v1.2.3_4 $v->qv(0); say "$v"; # 1.2.3_4
rc
Specifies the release candidate value. This is currently unused and reserved for future release.
target
Specifies the target formatting for the version string. By default this is
perl
and is the only supported value for now. In future release, other format types will be supported, such asopensource
.type
Specifies the version type. Possible values are
dotted
for dotted decimal versions such asv1.2.3
ordecimal
for decimal versions such as1.002003
parse
Provided with a version string, and this will parse it and return a new Changes::Version object.
Currently, only 2 version types are supported: dotted decimal
and decimal
v1.2
1.2345.6
v1.23_4
1.2345
1.2345_01
are all legitimate version strings.
If an error occurred, this will return an error.
METHODS
alpha
Sets or gets the alpha
fragment integer of the version.
Setting this to undef
effectively removes it.
Returns a number object
as_string
Returns a version string properly formatted according to the type
set with "type" and other parameters sets such as "qv", "padded" and "pretty"
Resulting value is cached, which means the second time this is called, the cached value will be returned for speed.
Any change to the version object parameters, and this will force the re-formatting of the version string.
For example:
my $v = Changes::Version->new( 'v1.2.3_4' );
# This is a version of type 'dotted' for dotted decimal
say "$v"; # v1.2.3_4
# Changing the patch level
$v->inc( 'patch' );
# Now forced to re-format
say "$v"; # v1.2.4
# No change, using the cache
say "$v"; # v1.2.4
beta
The beta fragment integer of the version. This is currently unused and reserved for future release of this class.
compat
Boolean. When enabled, this will ensure the version formatting is strictly compliant with the version module. Default to false.
dec
Provided with a version fragment, and an optiona integer, and this will decrease the version fragment value by as much. If no integer is provided, the default decrement is 1.
my $v = Changes::Version->new(
major => 1,
minor => 2,
patch => 3,
alpha => 4,
);
say "$v"; # v1.2.3_4;
$v->dec( 'alpha' );
say "$v"; # v1.2.3_3;
$v->dec( 'patch', 2 );
say "$v"; # v1.2.1
my $v = Changes::Version->new( 'v1.2.3.4.5.6.7_8' );
# Decrease the 5th fragment
$v->dec(5);
say "$v"; # v1.2.3.4.4.0.0
Any change to a fragment value will reset the lower fragment values to zero. Thus:
changing the
major
value will resetminor
andpatch
to 0 andalpha
toundef
changing the
minor
value will resetpatch
to 0 andalpha
toundef
changing the
patch
value will resetalpha
toundef
changing the nth fragment value will reset all fragment value after that to 0
If you pass a fragment that is an integer and it is outside the maximum number of fragments, it will automatically expand the number of version fragments and initialise the intermediary fragments to 0. A fragment as an integer starts at 1.
Using the example above:
$v->dec(10);
say "$v"; # v1.2.3.4.5.6.7.0.0.0
The 10th element is set to 0 because it does not exist, so it cannot be decreased.
dec_alpha
This is a shortcut for calling "dec" on fragment alpha
dec_beta
This is a shortcut for calling "dec" on fragment beta
dec_major
This is a shortcut for calling "dec" on fragment major
dec_minor
This is a shortcut for calling "dec" on fragment minor
dec_patch
This is a shortcut for calling "dec" on fragment patch
default_frag
my $v = Changes::Version->new( 'v1.2.3_4' );
my $default = $v->default_frag; # By default 'minor'
$v->default_frag( 'major' );
$v++; # Version is now v2.2.3_4
String. Sets or gets the name or the integer value for the version fragment. Supported value can be major
, minor
. patch
, alpha
, or an integer.
Returns a scalar object
extra
Sets or gets an array reference of version fragments starting from 1
for major
, 2
for minor
, 3
for patch
, etc. For example:
my $v = Changes::Version->new( 'v1.2.3.4.5.6.7_8' );
my $a = $v->extra; # contains 4, 5, 6, 7
Note that alpha
is not accessible via digits, but only using "alpha"
You should not be accessing this directly.
Returns an array object
format
my $v = Changes::Version->parse( "5.0.6_2" );
say $v->format( "%R%d" ); # 5.0.6
This formats the version string. It takes a string representing a pattern, or an array reference of pattern elements and returns a regular string.
If an error occurred, it sets an error object and returns undef
in scalar context, or an empty list in list context.
See also "pattern" to get or set a pattern used by "as_string"
See also below the possible patterns
inc
Same as "dec", but increasing instead of decreasing.
inc_alpha
This is a shortcut for calling "inc" on fragment alpha
inc_beta
This is a shortcut for calling "inc" on fragment beta
inc_major
This is a shortcut for calling "inc" on fragment major
inc_minor
This is a shortcut for calling "inc" on fragment minor
inc_patch
This is a shortcut for calling "inc" on fragment patch
is_alpha
Returns true if "alpha" has a value set.
is_qv
Returns true if "qv" is set to true, false otherwise.
major
Sets or gets the major
fragment of the version string.
my $v = Changes::Version->new( 'v1.2.3_4' );
my $major = $v->major; # 1
$v->major(3);
say "$v"; # v3.2.3_4
Setting this to undef
effectively removes it.
Returns a number object
minor
Sets or gets the minor
fragment of the version string.
my $v = Changes::Version->new( 'v1.2.3_4' );
my $minor = $v->minor; # 2
$v->minor(3);
say "$v"; # v1.3.3_4
Setting this to undef
effectively removes it.
Returns a number object
normal
Returns a new Changes::Version object as a normalised version, which is a dotted decimal format with the v
prefix.
If an error occurred, an error is returned.
numify
Returns a new Changes::Version object as a number, which represent a decimal-type version
Contrary to version if there is an alpha
value set, it will add it to the numified version.
my $v = Changes::Version->new(
major => 1,
minor => 2,
patch => 3,
alpha => 4,
);
say $v->numify; # 1.002003_4
version would yields a different, albeit wrong result:
perl -Mversion -lE 'say version->parse("v1.2.3_4")->numify'
would wrongly return 1.002034
and not 1.002003_4
perl -Mversion -lE 'say version->parse("1.002034")->normal'
then yields v1.2.34
If an error occurred, an error is returned.
original
Sets or gets the original string. This is set by "parse"
Returns a scalar object
padded
Boolean. Sets or ges whether the resulting version string of type decimal
should be '0' padded or not. Default to pad with zeroes decimal numbers.
For example:
my $v = Changes::Version->new(
major => 1,
minor => 2,
patch => 30,
type => 'decimal',
padded => 1,
);
say "$v"; # 1.002030
$v->padded(0);
say "$v"; # 1.00203
Returns a boolean object
patch
Sets or gets the patch
fragment of the version string.
my $v = Changes::Version->new( 'v1.2.3_4' );
my $patch = $v->patch; # 3
$v->patch(5);
say "$v"; # v1.3.5_4
Returns a number object
pattern
Sets or gets a format pattern. This returns a regular string, or undef
if no pattern has been set.
See also the list of patterns
pretty
Boolean. When enabled, this will render version number for decimal type a bit cleaner by separating blocks of 3 digits by an underscore (_
). This does not work on dotted decimal version numbers such as v1.2.3
or on version that have an alpha
set up.
my $v = Changes::Version->new(
major => 1,
minor => 2,
patch => 30,
type => 'decimal',
);
Returns a boolean object
qv
Boolean. When enabled, this will prepend the dotted decimal version strings with v
. This is true by default.
my $v = Changes::Version->new(
major => 1,
minor => 2,
patch => 3,
alpha => 4,
);
say "$v"; # v1.2.3_4
$v->qv(0);
say "$v"; # 1.2.3_4
Returns a boolean object
rc
Sets or gets the release candidate value. This is currently unused and reserved for future releases.
Returns a scalar object
satisfy
$v->satisfy( $predicate );
$v = Changes::Version->parse( '0.1.1' );
$v->satisfy( '0.1.1' ); # true
$v->satisfy( '0.1.1', '> 0, < 0.2, != 0.1.0' ); # true
$v = Changes::Version->parse( '0.2.4' );
$v->satisfy( '0.2.5..0.3.4' ); # false
# or, using it as a class function:
Changes::Version->satisfy( '0.1.1', '0.1.1' ); # true
Changes::Version->satisfy( '0.1.1', '> 0, < 0.2, != 0.1.0' ); # true
Changes::Version->satisfy( '0.2.4', '0.2.5..0.3.4' ); # false
Determines if a v-string satisfy a predicate. The predicate is a list of simple predicates, each one must be satisfied (that is, an and). Simple predicates takes one of three forms:
'0.1.2' - exact match
'>= 3.14.15' - (relational operator) (v-string)
'5.6 .. 10.8' - meaning '>= 5.6, <= 10.8'
A grammar for predicates in Parse::RecDescent-like syntax is:
<p> : <p0> (',' <p>)*
<p0>: <v-string> # the same as '==' <v-string>
| <op> <v-string>
| <v-string> '..' <v-string> # the same as ">= <v-string1>, <= <v-string2>"
<op>: '==' | '!=' | '<=' | '>=' | '<' | '>'
Spaces are irrelevant in predicates.
stringify
This is an alias for "as_string"
target
Sets or gets the target format. By default this is perl
. This means that "as_string" will format the version string for perl
. In future release of this class, other format wil be supported, such as opensource
Returns a scalar object
type
Sets or gets the version type. Currently, supported values are dotted
for dotted decimal versions such as v1.2.3
, and decimal
for decimal versions such as 1.002003
.
Returns a scalar object
OVERLOADED OPERATIONS
The following operations are overloaded, and internally relies on version to return the value. See also overload for more information.
Note that calling the version object with any operations other than those listed below will trigger a warning, if warnings are enabled with warnings and undef
is return in scalar context or an empty list in list context.
stringification
Returns value from "as_string"
0+
Returns value from "numify"
<=>
Compares two versions. If the other version being compared is not a Changes::Version, it is made one before comparison actually occurs.
Note that,
version
core module states in its documentation that: "alpha" version objects (where the version string contains a trailing underscore segment) compare as less than the equivalent version without an underscore."$bool = version->parse("1.23_45") < version->parse("1.2345"); # TRUE
However, as of perl v5.10, this is not true. The above will actually return false, not true. And so will the following:
perl -Mversion -lE 'say version->parse("v1.002003") > version->parse("v1.002003_4");'
This is on my bucket list of things to improve.
cmp
Same as above.
bool
+
,-
,*
,/
When performing those operations, it will use the value of the fragment of the version set with "default_frag", which, by default, is
minor
.It returns a new Changes::Version object reflecting the new version value. However, if the operation is swapped, with the version object on the right-hand side instead of the left-hand side, this will return a regular number.
my $vers = Changes::Version->new( 'v1.2.3_4' ); my $new_version_object = $vers + 2; # Now v1.4.3_4 (minor has been bumped up by 2) $vers->default_frag( 'major' ); my $new_version_object = $vers + 2; # Now v3.2.3_4 (this time, 'major' was increased)
But, when swapped:
my $vers = Changes::Version->new( 'v1.2.3_4' ); my $n = 3 + $vers; # yields 5 (using the 'minor' fragment by default) $vers->default_frag( 'major' ); my $n = 3 + $vers; # yields 4 (this time, using the 'major' fragment)
+=
,-=
,*=
,/=
In this operations, it modifies the current object with the operand provided and returns the current object, instead of creating a new one.
my $vers = Changes::Version->new( 'v1.2.3_4' ); # By default, using the 'minor' fragment $vers += 1; # version is now v2.2.3_4 $vers->default_frag( 'alpha' ); $vers /= 2; # version is now v1.2.3_2
++
,--
When using those operations, it updates the current object directly and returns it. For example:
my $vers = Changes::Version->new( 'v1.2.3_4' ); # By default, using the 'minor' fragment $vers++; # version is now v1.3.3_4
PATTERNS
The following patterns can be used to format the version string.
%A
my $v = Changes::Version->parse( "5.0.6_2" ); say $v->format( '%A' ); # _2
This will return the alpha version, if any, prepended with an underscore.
If there is no alpha version, it returns an empty string.
%a
my $v = Changes::Version->parse( "5.0.6_2" ); say $v->format( '%a' ); # 2
This will return the
alpha
fragment value, if any.If there is no
alpha
fragment value, it returns an empty string.%D
my $v = Changes::Version->parse( "5.0.6.1.2.3.4_2" ); say $v->format( '%D' ); # 0.6.1.2.3.4 my $v = Changes::Version->parse( "5.0.6" ); say $v->format( '%D' ); # 0.6
This will return the
minor
,patch
, and any extra fragments.This is designed for dotted-decimal types, and
minor
, andpatch
will always return a number, possibly0
%d
my $v = Changes::Version->parse( "5.0.6.1.2.3.4_2" ); say $v->format( '%D' ); # .0.6.1.2.3.4 my $v = Changes::Version->parse( "5.0.6" ); say $v->format( '%D' ); # .0.6
This is similar to
%D
, but will prepend a dot if the value is not null.This is designed so you can write:
my $v = Changes::Version->parse( "5.0.6.1.2.3.4_2" ); say $v->format( '%R%d%A' ); # 5.0.6.1.2.3.4_2 my $v = Changes::Version->parse( "5" ); say $v->format( '%R%d%A' ); # 5.0.0
%M
my $v = Changes::Version->parse( "5.2.6_3" ); say $v->format( '%M' ); # 2
This returns the
minor
part of the version.If there is no
minor
fragment value, it returns an empty string.%m
my $v = Changes::Version->parse( "5.2.6_3" ); say $v->format( '%m' ); # .2
This is similar to
%M
, but will prepend a dot if the value is not null.%N
my $v = Changes::Version->parse( "5.2.6" ): say $v->format( '%R.%N' ); # 5.002006
This returns the
minor
andpatch
value of a dotted-decimal version as numified version.%n
my $v = Changes::Version->parse( "5.2.6" ): say $v->format( '%R%n' ); # 5.002006 say $v->format( '%n' ); # .002006
This is similar to
%N
, but will prepend a dot if the value is not null.%P
This returns the
patch
fragment value of the version, if any.If there is no
patch
fragment value, it returns an empty string.%R
This returns the
major
fragment value of the version, if any.If there is no
major
fragment value, it returns an empty string.%U
my $v = Changes::Version->parse( "5.2.6" ): say $v->format( '%R.%U' ); # 5.002_006 say $v->format( '%U' ); # 002_006
This returns the
minor
andpatch
value of a dotted-decimal version as numified version using the underscore to separate theminor
and thepatch
fragments.%u
my $v = Changes::Version->parse( "5.2.6" ): say $v->format( '%R%u' ); # 5.002_006 say $v->format( '%u' ); # .002_006
This is similar to
%U
, but will prepend a dot if the value is not null.
AUTHOR
Jacques Deguest <jack@deguest.jp>
SEE ALSO
Changes, Changes::Release, Changes::Group, Changes::Change and Changes::NewLine
version, Perl::Version, version::Internals, Data::VString, "Version Strings" in perldata
"Version Formats" in CPAN::Meta::Spec
http://www.modernperlbooks.com/mt/2009/07/version-confusion.html
https://xdg.me/version-numbers-should-be-boring/
https://en.wikipedia.org/wiki/Software_versioning
COPYRIGHT & LICENSE
Copyright(c) 2022 DEGUEST Pte. Ltd.
All rights reserved
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.