NAME

Data::VString - Perl extension to handle v-strings (often used as version strings)

SYNOPSIS

use Data::VString qw(parse_vstring format_vstring vstring_satisfy);

# going from '0.0.1' to "\x{0}\x{0}\x{1}" and back
$i_vstring = parse_vstring($vstring);
$vstring = format_vstring($i_vstring);

vstring_satisfy($vstring, $predicate)

DESCRIPTION

Most of the time, the so-called version numbers are not really numbers, but tuples of integers like '0.2.3'. With this concept of version, '0.1' is the same as '0.01'. The ordering of such tuples is usually defined by comparing each part. And that makes

'0.1' > '0.2' 
'0.2.1' < '0.1.3'
'0.11.10' > '0.10.10.10' 

and also '0.1' > '0.1.0' (because the first one is shorter). There is also no need to define how many integers to accept in the tuple, with '0.0.1.2.34.4.580.20' being a nice version.

Perl had (and still has) this concept as v-strings. They had even deserved a syntax on their own: v1.20.300.4000 or 100.111.1111 (a literal with two or more dots). But their fate is sealed: in "Version Strings" in perldata of 5.8 we read:

Note: Version Strings (v-strings) have been deprecated.  
They will not be available after Perl 5.8.  The marginal 
benefits of v-strings were greatly outweighed by the 
potential for Surprise and Confusion.

This module revives them as a simple module implementation. Version strings are well suited in many version "numbering" schemes and straightforward (if you always remember they are not numbers). In Perl, most of the confusion lies in that 0.1 as a literal is a number and sorts like a number, while 0.1.0 is a v-string and sorts like a v-string. Also from "Version Strings" in perldata:

A literal of the form "v1.20.300.4000" is parsed as a string composed
of characters with the specified ordinals.  This form, known as
v-strings, provides an alternative, more readable way to construct
strings, rather than use the somewhat less readable interpolation form
"\x{1}\x{14}\x{12c}\x{fa0}".  This is useful for representing Unicode
strings, and for comparing version "numbers" using the string compari-
son operators, "cmp", "gt", "lt" etc.  If there are two or more dots in
the literal, the leading "v" may be omitted.

  print v9786;              # prints UTF-8 encoded SMILEY, "\x{263a}"
  print v102.111.111;       # prints "foo"
  print 102.111.111;        # same

This text reveals how this notion of version as tuple of integers can be represented efficiently if one agreeds that each part is limited to 16 bits (0-65565), which is more than enough for practical software versioning schemes. Converting each part to a Unicode character, the version string ends up like a Unicode string which can be compared with the usual string comparators.

Here, functions are provided for converting between v-strings (like '6.2.28') and their internal representation ("\x{6}\x{2}\x{1C}") and to test them against other v-strings.

parse_vstring
$i_vstring = parse_vstring($vstring);

parse_vstring('0.1.2') # return "\x{0}\x{1}\x{2}"

Converts a v-string into its internal representation (the string made up the Unicode characters given by the ordinals specified in v-string parts).

The syntax of a v-string can be defined by the following syntax rule (in P::RD style)

<v-string>: /\d+/ ( /[._]/ /\d+/ )*

For the reverse operation, see format_vstring.

format_vstring
$vstring = format_vstring($i_vstring)

Converts the internal representation of a v-string into a readable v-string. It does the reverse operation of parse_vstring.

vstring_satisfy
vstring_satisfy($vstring, $predicate);

vstring_satisfy('0.1.1', '0.1.1'); # true
vstring_satisfy('0.1.1', '> 0, < 0.2, != 0.1.0'); # true
vstring_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'  
'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.

EXPORT

None by default. parse_vstring, format_vstring and vstring_satisfy can be exported on demand.

SEE ALSO

"Version Strings" in perldata

This module is a companion for the JSAN module Data.VString. This one implements the Perl side while the other will implement the JavaScript side.

BUGS

Please report bugs via CPAN RT http://rt.cpan.org/NoAuth/Bugs.html?Dist=Data-VString.

AUTHOR

Adriano R. Ferreira, <ferreira@cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2005 by Adriano R. Ferreira

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.