Michael G Schwern wrote:
> Let's count the different ways we might have to parse a version.
> 
> X     ok, sort it as a number.
> X.Y   hopefully that's a decimal number and not a dotted pair
> X.Y_Z oh right, alpha versions.  Strip _Z off and sort as X.Y
> X.Y.Z dotted triad.  split and compare X, Y and Z individually
> vX.Y  dotted pair?

I step away from the computer to spend a quiet Shabbat with my family and look
what happens! ;-)

What the current discussion is missing is that version.pm came _after_ this mess
was already in effect.  It was written as reaction to the madness.  It is the
One Version Module to Rule Them All (we were listening to /The Hobbit/ on our
recent Spring Break to the Midwest).

And both X.Y.Z and vX.Y were originally encoded as v-strings, which were
introduced in Perl 5.6.0 as an alternate method for $VERSION assignments.
v-strings were a tokenizer hack, which took perfectly readable source-code and
rendered it as funny characters (I hope my e-mail client renders these like my
shell does):

$ perl -e 'print v1.2'


In order to do anything with v-strings, you had to know /a priori/ that they
were already there and use printf "%vd" formatting to return them to human
readable form.  Before magic v-strings (5.8.1), you couldn't even tell that the
v-string notation had been used at all!  Perl's own UNIVERSAL::VERSION had some
code to handle v-strings, but it wasn't that hard to confuse it.

Version objects, which is to say version.pm, handle every single one of those
styles of $VERSION assignment, and sort them consistently in a documented
fashion (even the alpha releases) and they do it with any released Perl going
back to 5.005_04.  My primary mistake was not spending at least as much time on
the documentation as I did on the coding.  Trust me, I was as surprised as
anyone that Damian included version.pm in PBP; I wasn't ready for that yet...

It's an imperfect world.  If you (the module author) always use numeric versions
for CPAN release, the entire toolchain is perfectly happy.  If you always use
v1.2.3 notation, the entire toolchain works (and has for a while), though the
META.yml "exploded object notation" could be considered to be confusing.  The
biggest problem has always been module authors who switch from numeric to
extended without reading the documentation.  Yeah, if you use someone else's
module in your code, you are expected to at least read the POD.  /mea culpa/ if
I didn't write in 48 point type DON'T MIX NUMERIC AND EXTENDED VERSIONS WITHOUT
READING THIS THOROUGHLY!!!

I actually thought that PAUSE would refuse to accept a $VERSION that was less
than the current "latest"; perhaps it does now and didn't when Damian uploaded
Text::Autoformat.  That is the appropriate place to prevent this problem in the
first place, since once it is on CPAN/BACKPAN, all bets are off.

The urge to force $version->numify in META.yml is understandable, but it is
flawed.  While the numified $VERSION can be compared (with version.pm) to the
extended form, they are not the same thing.  There is information lost.  As
such, I would not suggest it be used as Michael is suggesting.

However, using $version->stringify() instead would be better than having
META.yml contain an object dump for $VERSION.  The version.pm object is
guaranteed to stringify to the same form as was original present in the source
file, which is the _only_ way to preserve the author's intention.  Since most of
the toolchain treats $VERSION as an atomic THING, and the few places which try
to compare one $VERSION to another are already wired up with version.pm, this
will work as any sane person would expect it to...

John

Reply via email to