develooper Front page | perl.perl5.porters | Postings from July 2009

Re: A Modest Proposal

Thread Previous | Thread Next
From:
David Golden
Date:
July 22, 2009 19:21
Subject:
Re: A Modest Proposal
Message ID:
5d4beb40907221920j102e20ecv41301ef395b1c72d@mail.gmail.com
On Wed, Jul 22, 2009 at 7:31 PM, John
Peacock<john.peacock@havurah-software.org> wrote:
> So I left Damian's API design tutorial at OSCON with my head buzzing.  In
> the haze afterwords, it occurred to me that this _should_ be sufficient
>
>    use version; our $VERSION = 1.2.3;
>
> to define a package $VERSION.  No version->new() or qv() required.  If you
> are running Perl 5.10.x you don't even need to include "use version"!
>
> Is that a good thing?  Should I work towards that minimalist goal?

My gut reaction is "not quite".  I have several reasons.  (And damn, I
really, really, need to finish my article on version numbers.)

At very least, it needs to be quoted:

    use version; our $VERSION = "v1.2.3";
    use version; our $VERSION = "1.002003";

You need to do this because of alpha versions.  There are subtle ways
it will break or do unexpected things if you use bare v-strings.

I also *strongly* advocate only teaching people to use leading "v".
It clearly disambiguates the cases visually between version tuples and
decimals.  Yes, the internals should be liberal in what they accept,
but code examples should teach that.

> The reason this is sufficient is that version.pm includes a
> version-object-aware UNIVERSAL::VERSION, which will upgrade the $VERSION
> scalar to a version object if needed to do a comparison (e.g. 'use package
> 1.0').  That deals with the runtime usage.

I think this is how it should have been done in the first place,
except that it should NON-DESTRUCTIVELY convert them to version
objects for comparison.

> 1) Module::Build
> 2) ExtUtils::MakeMaker
> 3) the PAUSE indexer

These are all fixable, if need be.

I'm actually a step ahead of you in one respect.  I have a working
blead patch that extends the package keyword in this way:

  package Foo v1.2.3;
  package Bar 1.002003;

The numbers are parsed using the exact same code that is used for "use
MODULE VERSION" and stored in the appropriate package's $VERSION
variable.

This of course would require perl 5.12, so doesn't help older perls,
but going forward it means that version numbers become literals, not
runtime expressions.  Thus, MM->parse_version can parse it directly
and avoid having to eval() an arbitrary string.  I think this is a
cleaner long-term interface than "use version; our $VERSION...".

> Opinions?  Brickbats?  What color should we paint this shed?

I'd like to go further on two topics:

(1) The pure-Perl version.pm code should remove the module autoloading
in UNIVERSAL::VERSION.  From what I can tell with my pidgin XS,
neither the 5.10 core UNIVERSAL::VERSION nor the code in version::vxs
does that.  If so, neither should version::vpp.

(2) Alpha versions should compare equal to a non-alpha version with
the same tuple components.  Once version.pm decides that something is
an alpha, it's not easy/obvious how someone can require that version
in a "use MODULE VERSION" line.  "use Foo 0.001_002" won't work
because Perl drops the underscore.  And "use Foo v0.1_2" has behavior
that varies a bit depending on what version of perl is used.  I
strongly feel that it's more user-friendly to leave "alpha" purely as
a PAUSE/CPAN distinction and not make users have to figure out the
right incantation on a use() line.

-- David

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About