David H. Adler wrote:
Tests pass. One "not numeric" warning:
t/00compile.........ok 1/6Argument "2.57_06" isn't numeric in subroutine
entry at t/lib/Test/More.pm line 670
This is the same warning I reported in an earlier message:
http://groups.google.com/group/perl.qa/msg/fee69dde25cf42ec
Given the wise counsel of a former Phalanx strategos ("every warning
your test suite throws is a bug which must be tracked down"), I spent
several hours looking at this this morning. To cut to the chase, it
will go away once v2.58 is uploaded to CPAN. If my analysis is correct,
it only occurs when a module author uses a version number containing an
underscore and when that is assigned as a *string* rather than a number
to the module's $VERSION.
More detailed explanation follows.
The test which is throwing the warning is the last test in t/00compile.t:
BEGIN { use_ok 'Test::Harness', 1.1601 }
Andy's test suite, apparently for reasons of backwards compatibility, is
testing against v0.42 of Test::More, which is included beneath the
t/lib/ directory. In v0.42, when use_ok is called with a version number
as the second argument, Test::Harness::import is called. Since
Test::Harness doesn't define an import method, it's really
Exporter::import which is being called. Exporter::import, in this
particular case, calls, in turn, Exporter::export, which calls
Exporter::as_heavy, which calls Exporter::Heavy::heavy_export, which,
deep in its guts, calls its VERSION method ...
$pkg->VERSION($sym);
... which is really UNIVERSAL::VERSION which, if supplied with an
argument, assumes that the argument is a number to be compared with the
minimum version number needed. But if, way back at the top of the
chain, the module author says,
$VERSION = '2.57_06';
that 2.57_06 does not numerify, so the "non-numeric argument" warning
gets thrown.
Got that? (Take a deep breath.)
I experimented with several other ways of assigning to $VERSION. Each
of the three following ways ...
$VERSION = '2.5706';
$VERSION = 2.57_06;
$VERSION = 2.5706;
... avoids the non-numeric warning. The first case numerifies
correctly; the latter two already qualify as numbers in Perl. However,
each of these three cases fails the second test in Andy's t/version.t
file ...
ok( $ver =~ /^2.\d\d(_\d\d)?$/, "Version is proper format" );
which says that if there is anything after the "hundredths" place in the
version number, an underscore is mandatory. Relaxing this requirement ...
ok( $ver =~ /^2.\d\d(_?\d\d)?$/, "Version is proper format" );
... allows each of the three cases above to pass t/version.t and
simultaneously avoid the non-numeric warning.
Now, I believe I've read somewhere that assigning a string containing an
underscore to $VERSION is a way to tell the CPAN indexer to label this
particular version of a module as a developer's release. I suppose
someone could think of a different way of doing that that would not run
the risk of a non-numeric warning, but it's probably not important
enough to warrant many brain cycles.
But it raises the question of whether one should ever assign a string to
a module's $VERSION unless it were a string like a CVS version number.
I consulted the web versions of three relevant man pages:
http://perldoc.perl.org/perlmod.html#Perl-Modules-module
http://perldoc.perl.org/perlmodlib.html#Guidelines-for-Module-Creation
http://perldoc.perl.org/Exporter.html#Module-Version-Checking
Only the second of these pages gives an example where a non-CVS version
number is stringified before being assigned to $VERSION ...
$VERSION = "0.01"
... but it doesn't provide a rationale for the stringification. The
other two pages suggest that, with the exception of CVS-type strings,
what should be assigned to $VERSION is what qualifies in Perl as a
number. (My own thinking is that I'll go back to using only numbers,
not stringified numbers, in my own modules, but this probably falls
somewhere between TMTOWTDI and YMMV.)
Jim Keenan