Grokbase Groups Perl qa January 2008
FAQ
So we are told the way to mark a module as development is to use an
underbar in the version number:

$VERSION= "1.23_01";

but this will produce warnings if you assert a required version
number, as the version isn't numeric.

So the standard response is to do

$VERSION= eval $VERSION;

on the next line. This means that MakeMaker sees "1.23_01" but Perl
internal code for doing version checks sees "1.2301". This is all fine
and dandy with pure perl modules.

BUT, if the module is "bog standard" and uses XS this is a recipe for
a fatal error. XS_BOOT_VERSIONCHECK will compare "1.23_01" to "1.2301"
and decide that they are different versions and die.

The solution I came up with was to add

XS_VERSION=> eval MM->parse_version("Filename"),

to the WriteMakefile() call in the Makefile.PL.

But to me this is unsatisfactory. It means either duplicating code
because there is normally something like:

VERSION_FROM => "DB_File.pm"

or something like it in the WriteMakefile() arguments. Even if you use
a variable so that you end up with

$file= "DB_File.pm";
WriteMakefile(
XS_VERSION=> eval MM->parse_version($file),
VERSION_FROM => $file,
...
);

you are still duplicating effort, essentially parsing the version
twice, no biggie really in terms of CPU cycles, but somewhat
distasteful nevertheless.

I thought of fixing XS_BOOT_VERSIONCHECK so that when there is a
mismatch it checks for an underbar and then evals the string first,
but this didnt seem either fun (its C code after all) or really all
that great a solution since on older perls it wouldnt help at all.

About the best thing I can think of is making it so that the version
checked in XS_BOOT_VERSIONCHECK is ALWAYS numeric. IOW, MakeMaker
should do the eval trick itself. I think that this would work out,
but im not sure of the ramifications. (its late).

Anyway, i welcome any thoughts anyone might have on this.

Ive cross posted this because I think this is as much a Perl core dev
issue as it is a Quality Assurance issue as well as a MakeMaker issue.
I apologise if this irritates anyone.

Cheers,
Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

Search Discussions

  • Zefram at Jan 7, 2008 at 1:26 am

    demerphq wrote:
    $VERSION= "1.23_01";
    I've not seen that form, but

    $VERSION = 1.23_01;

    which of course doesn't put the underscore in the string value. This
    still delimits the subrevision portion, but without forcing anything
    else to handle the delimiter.
    but this will produce warnings if you assert a required version
    number, as the version isn't numeric.
    I've found a similar problem when attempting to include underscores in
    dependency version numbers in Makefile.PL. Now I never use underscores in
    version numbers in any context, because it's the only way to completely
    eliminate that class of problems. I don't think the underscore is
    essential; the bare number has all the right semantics, and a module
    author's numbering convention is generally clear from the Changes file.

    For my own modules I use three digits for each part of the version
    number, like the perl core, rather than the usual two for modules.
    This has the side effect of making the version number structure clearer.
    "1.023001" isn't difficult to tease apart.
    $VERSION= eval $VERSION;
    Dumb approach. Now you have two different values for $VERSION depending
    on how much of the code gets executed (read: depending on who's looking).
    It's a recipe for trouble, as in the case you note with XS.
    BUT, if the module is "bog standard" and uses XS this is a recipe for
    a fatal error. XS_BOOT_VERSIONCHECK will compare "1.23_01" to "1.2301"
    and decide that they are different versions and die.
    Presumably XS_BOOT_VERSIONCHECK should be stripping out underscores,
    and trailing zeroes too, to just compare the numerical values. Even if
    it operates purely on strings, this transformation is not difficult to
    do implicitly during the comparison.

    -zefram
  • John Peacock at Jan 7, 2008 at 11:15 am

    Zefram wrote:
    demerphq wrote:
    $VERSION= "1.23_01";
    I've not seen that form, but

    $VERSION = 1.23_01;

    which of course doesn't put the underscore in the string value. This
    still delimits the subrevision portion, but without forcing anything
    else to handle the delimiter.
    Plus it defeats the original purpose of having the package name created by
    EU::MM or M::B display an underscore (and hence giving the CPAN indexer the
    chance to not index this file as "latest".

    John
  • Eric Wilhelm at Jan 7, 2008 at 3:21 am
    # from demerphq
    # on Sunday 06 January 2008 16:54:
    So we are told the way to mark a module as development is to use an
    underbar in the version number:

    $VERSION= "1.23_01";

    but this will produce warnings if you assert a required version
    number, as the version isn't numeric.
    Does *any* code besides pause actually decide that "this is an alpha"?

    I think that's the $dist =~ /\d\.\d+_\d/ bit around line 1474 in
    mldistwatch. $dist = $self->{DIST} though and I'm getting lost in the
    BIGLOOP bit of checkfornew() as to whether that's looking at the
    extracted $VERSION, the META.yml $VERSION, or the bit in the filename.
    (Hmm, I guess line 1487's "$dist =~ /\.pm..." implies filename.)

    So, if all of the alpha-y magic is just in the filename, what would
    happen if "make dist" had an "alpha" option which injected "TRIAL" into
    the filename? Would that appropriately tickle the other half of that
    if() at line 1474?

    Or a flag in META.yml?

    Then we can do away with all of the underscores?

    --Eric
    --
    perl -e 'srand; print join(" ",sort({rand() < 0.5}
    qw(sometimes it is important to be consistent)));'
    ---------------------------------------------------
    http://scratchcomputing.com
    ---------------------------------------------------
  • Eric Wilhelm at Jan 7, 2008 at 9:47 am
    # from Eric Wilhelm
    # on Sunday 06 January 2008 19:21:
    So, if all of the alpha-y magic is just in the filename, what would
    happen if "make dist" had an "alpha" option which injected "TRIAL"
    into the filename?  Would that appropriately tickle the other half of
    that if() at line 1474?
    Well, sure enough: it does not go in the index. The search.cpan.org
    code doesn't show the "alpha version" bit though. Apparently
    kobesearch is a bit slow on the mirroring, so not sure what happens
    there yet.

    curl -s http://cpan.org/modules/02packages.details.txt.gz | \
    gunzip -c | grep Date-Piece

    http://search.cpan.org/dist/Date-Piece/

    --Eric
    --
    Issues of control, repair, improvement, cost, or just plain
    understandability all come down strongly in favor of open source
    solutions to complex problems of any sort.
    --Robert G. Brown
    ---------------------------------------------------
    http://scratchcomputing.com
    ---------------------------------------------------
  • Michael G Schwern at Jan 7, 2008 at 3:46 am

    demerphq wrote:
    So we are told the way to mark a module as development is to use an
    underbar in the version number:

    $VERSION= "1.23_01";

    but this will produce warnings if you assert a required version
    number, as the version isn't numeric.
    We talked about this recently on module-build@perl.org. Specifically how much
    the convention sucks and replacing it with META.yml info.
    http://www.nntp.perl.org/group/perl.module.build/2007/12/msg1151.html


    --
    Life is like a sewer - what you get out of it depends on what you put into it.
    - Tom Lehrer
  • Yitzchak Scott-Thoennes at Jan 7, 2008 at 5:47 am
    On Sun, January 6, 2008 4:54 pm, demerphq wrote:
    So we are told the way to mark a module as development is to use an
    underbar in the version number:

    $VERSION= "1.23_01";


    but this will produce warnings if you assert a required version number, as
    the version isn't numeric.

    So the standard response is to do

    $VERSION= eval $VERSION;

    on the next line. This means that MakeMaker sees "1.23_01" but Perl
    internal code for doing version checks sees "1.2301". This is all fine and
    dandy with pure perl modules.

    BUT, if the module is "bog standard" and uses XS this is a recipe for
    a fatal error. XS_BOOT_VERSIONCHECK will compare "1.23_01" to "1.2301" and
    decide that they are different versions and die.
    See perlmodstyle:
    If you want to release a 'beta' or 'alpha' version of a module but
    don't want CPAN.pm to list it as most recent use an '_' after the
    regular version number followed by at least 2 digits, eg. 1.20_01. If
    you do this, the following idiom is recommended:

    $VERSION = "1.12_01";
    $XS_VERSION = $VERSION; # only needed if you have XS code
    $VERSION = eval $VERSION;
  • Demerphq at Jan 7, 2008 at 9:15 am

    On 07/01/2008, Yitzchak Scott-Thoennes wrote:
    On Sun, January 6, 2008 4:54 pm, demerphq wrote:
    So we are told the way to mark a module as development is to use an
    underbar in the version number:

    $VERSION= "1.23_01";


    but this will produce warnings if you assert a required version number, as
    the version isn't numeric.

    So the standard response is to do

    $VERSION= eval $VERSION;

    on the next line. This means that MakeMaker sees "1.23_01" but Perl
    internal code for doing version checks sees "1.2301". This is all fine and
    dandy with pure perl modules.

    BUT, if the module is "bog standard" and uses XS this is a recipe for
    a fatal error. XS_BOOT_VERSIONCHECK will compare "1.23_01" to "1.2301" and
    decide that they are different versions and die.
    See perlmodstyle:
    If you want to release a 'beta' or 'alpha' version of a module but
    don't want CPAN.pm to list it as most recent use an '_' after the
    regular version number followed by at least 2 digits, eg. 1.20_01. If
    you do this, the following idiom is recommended:

    $VERSION = "1.12_01";
    $XS_VERSION = $VERSION; # only needed if you have XS code
    $VERSION = eval $VERSION;
    im not convinced this actually does anything. ISTR i had to roll my
    own "parse out the $XS_VERSION code" thingee for DDS.

    Yves

    --
    perl -Mre=debug -e "/just|another|perl|hacker/"
  • John Peacock at Jan 7, 2008 at 11:27 am

    demerphq wrote:
    $VERSION = "1.12_01";
    $XS_VERSION = $VERSION; # only needed if you have XS code
    $VERSION = eval $VERSION;
    im not convinced this actually does anything. ISTR i had to roll my
    own "parse out the $XS_VERSION code" thingee for DDS.
    I;m very onfident that the recommended recipe DTRT. XS_VERSION_BOOTCHECK used
    to do a simplistic strcmp (ARG) prior to version objects being added to the
    core. The issue was always if you didn't explicitly specify an XS_VERSION in
    your Perl code, then EU::MM and M::B would be forced to guess, and that could be
    disastrous. Whatever literal string exists in the XS file itself, would be
    compared with whatever string representation that EU::MM/M::B would concoct.
    Even a trailing zero in the XS file would fail if the $VERSION assignment in the
    Perl module wasn't quoted.

    In 5.10.0 and forward, XS_VERSION_BOOTCHECK upgrades the requested XS_VERSION
    scalar to a version object and compares that against the XS_VERSION in the XS
    code (or falls back to the modules $VERSION if that doesn't exist).

    John

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupqa @
categoriesperl
postedJan 7, '08 at 12:54a
activeJan 7, '08 at 11:27a
posts9
users6
websiteqa.perl.org

People

Translate

site design / logo © 2018 Grokbase