Perl version string: why use EVAL EXPR?

2019-01-24 00:55发布

问题:

I just took notice to this generated by Catalyst.pl. It is obviously some sort of unannotated hack. What is the advantage of setting up a version string like this? I can't even figure out what they're trying to do.

our $VERSION = '0.01';
$VERSION = eval $VERSION;

回答1:

Version numbers are complex in Perl. Here's an excellent overview for those looking for the gory details. It might surprise you how many subtle ways there are to get things wrong...

The direct answer to your question though, is that different things expect different formats. For CPAN, you care about development versions for example, as a string. For runtime, you care about them as a number.

Consider the case of $VERSION = "0.01_001". eval converts it to the number 0.01001 correctly.



回答2:

From perlmodstyle: Version numbering

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:

  1. $VERSION = "1.12_01";
  2. $XS_VERSION = $VERSION; # only needed if you have XS code
  3. $VERSION = eval $VERSION;

With that trick MakeMaker will only read the first line and thus read the underscore, while the perl interpreter will evaluate the $VERSION and convert the string into a number. Later operations that treat $VERSION as a number will then be able to do so without provoking a warning about $VERSION not being a number.



回答3:

The eval converts the string "0.001_001" to a number, following the rules for Perl numeric literals (which allow underscores for legibility). The result is the number 0.001001.

Without the eval, the string is converted to a number following the rule for converting strings, which stops at the first non-numeric character.

E.g.: perl -e 'print "0.001_001" + 0'



回答4:

I may be misremembering this, but I think some automated code parsers like to see the line of code:

 our $VERSION = '0.01';

But you really want $VERSION to hold a float instead of a string.

You may want to read this article, I know I am going to.

Oh, dear god, now I remember why I use

our $VERSION = 20100903;

style version numbers. That is just insane. I love Perl, but that is pure, refined, concentrated insanity. I won't try to summarize David Golden's article. You just have to read it and cry.