I've attached a patch to bring Module::Build up to date with the current [dev release] of version.pm. There are a couple of things I want to call to your attention:
1) the pure Perl version.pm code vpp.pm now requires both locale and POSIX to be loaded, to deal with locales where the decimal point is not a period (e.g. a comma). I have tried to make this dependency less onerous by using 'require' so that no symbols are exported into M::B's address-space. 2) I have implemented all of the overloads in Perl that the XS code was handling (previously several of the methods were autogenerated). 3) I am considering adding: use version $VERSION => '1.002'; as an alternate syntax for use version; $VERSION = version->new('1.002'); but this will require that M::B (and EU::MM) support this syntax. You can see the propose code commented out in the patch. This patch is *not* intended to be applied as is; it is for discussion purposes only. John -- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4501 Forbes Blvd Suite H Lanham, MD 20706 301-459-3366 x.5010 fax 301-429-5747
=== lib/Module/Build/Version.pm ================================================================== --- lib/Module/Build/Version.pm (revision 2012) +++ lib/Module/Build/Version.pm (local) @@ -84,6 +84,14 @@ sub {return bless version::qv(shift), $class } unless defined(&{"$callpkg\::qv"}); +# if (@_) { # must have initialization on the use line +# if ( defined $_[2] ) { # CVS style +# $_[0] = version::qv($_[2]); +# } +# else { +# $_[0] = version->new($_[1]); +# } +# } } 1; @@ -92,9 +100,10 @@ package version::vpp; use strict; -use Scalar::Util; +use locale; use vars qw ($VERSION @ISA @REGEXS); -$VERSION = 0.67; +$VERSION = "0.69_01"; +$VERSION = eval $VERSION; push @REGEXS, qr/ ^v? # optional leading 'v' @@ -104,16 +113,24 @@ /x; use overload ( - '""' => \&stringify, - 'cmp' => \&vcmp, - '<=>' => \&vcmp, + '""' => \&stringify, + '0+' => \&numify, + 'cmp' => \&vcmp, + '<=>' => \&vcmp, + 'bool' => \&vbool, + 'nomethod' => \&vnoop, ); sub new { my ($class, $value) = @_; my $self = bless ({}, ref ($class) || $class); + require POSIX; + my $currlocale = POSIX::setlocale(&POSIX::LC_ALL); + my $radix_comma = ( POSIX::localeconv()->{decimal_point} eq ',' ); + POSIX::setlocale(&POSIX::LC_ALL, 'C') if $radix_comma; + if ( not defined $value or $value =~ /^undef$/ ) { # RT #19517 - special case for undef comparison # or someone forgot to pass a value @@ -125,14 +142,7 @@ $value = 'v'.$_[2]; } - # may be a v-string - if ( $] >= 5.006_002 && length($value) >= 3 && $value !~ /[._]/ ) { - my $tvalue = sprintf("%vd",$value); - if ( $tvalue =~ /^\d+\.\d+\.\d+$/ ) { - # must be a v-string - $value = $tvalue; - } - } + $value = _un_vstring($value); # exponential notation if ( $value =~ /\d+e-?\d+/ ) { @@ -140,6 +150,11 @@ $value =~ s/(0+)$//; } + # if the original locale used commas for decimal points, we + # need to force the PV to be regenerated, since just changing + # the locale isn't sufficient (use harmless math operation) + $value += 0 if $radix_comma; + # This is not very efficient, but it is morally equivalent # to the XS code (as that is the reference implementation). # See vutil/vutil.c for details @@ -292,6 +307,8 @@ "ignoring: '".substr($value,$pos)."'"; } + POSIX::setlocale(&POSIX::LC_ALL, $currlocale) if $radix_comma; + return ($self); } @@ -451,6 +468,16 @@ return $retval; } +sub vbool { + my ($self) = @_; + return vcmp($self,$self->new("0"),1); +} + +sub vnoop { + require Carp; + Carp::croak("operation not supported with version object"); +} + sub is_alpha { my ($self) = @_; return (exists $self->{alpha}); @@ -459,20 +486,15 @@ sub qv { my ($value) = @_; - my $eval = eval 'Scalar::Util::isvstring($value)'; - if ( !$@ and $eval ) { - $value = sprintf("v%vd",$value); - } - else { - $value = 'v'.$value unless $value =~ /^v/; - } + $value = _un_vstring($value); + $value = 'v'.$value unless $value =~ /^v/; return version->new($value); # always use base class } sub _verify { my ($self) = @_; - if ( Scalar::Util::reftype($self) eq 'HASH' - && exists $self->{version} + if ( ref($self) + && eval { exists $self->{version} } && ref($self->{version}) eq 'ARRAY' ) { return 1; @@ -482,6 +504,19 @@ } } +sub _un_vstring { + my $value = shift; + # may be a v-string + if ( $] >= 5.006_000 && length($value) >= 3 && $value !~ /[._]/ ) { + my $tvalue = sprintf("%vd",$value); + if ( $tvalue =~ /^\d+\.\d+\.\d+$/ ) { + # must be a v-string + $value = $tvalue; + } + } + return $value; +} + # Thanks to Yitzchak Scott-Thoennes for this mode of operation { local $^W; @@ -496,6 +531,7 @@ my $version = eval "\$$class\::VERSION"; if ( defined $version ) { + local $^W if $] <= 5.008; $version = version::vpp->new($version); }