summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pod/perldelta.pod25
-rw-r--r--pod/perlfunc.pod16
-rw-r--r--pod/perlop.pod3
-rwxr-xr-xt/comp/require.t6
-rwxr-xr-xt/op/ver.t24
-rw-r--r--toke.c40
6 files changed, 88 insertions, 26 deletions
diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index d908567631..4fd3ce49bd 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -84,6 +84,18 @@ notation, 5.005_03 is the same as v5.5.30, and the first maintenance
version following v5.6.0 will be v5.6.1, which amounts to a floating point
value of 5.006_001).
+=item Literals of the form C<1.2.3> parse differently
+
+Previously, numeric literals with more than one dot in them were
+interpreted as a floating point number concatenated with one or more
+numbers. Such "numbers" are now parsed as strings composed of the
+specified ordinals.
+
+For example, C<print 97.98.99> used to output C<97.9899> in earlier
+versions, but now prints C<abc>.
+
+See L<Support for strings represented as a vector of ordinals> below.
+
=item Possibly changed pseudo-random number generator
In 5.005_0x and earlier, perl's rand() function used the C library
@@ -461,10 +473,12 @@ variables. See L<perlfunc/our>.
=head2 Support for strings represented as a vector of ordinals
-Literals of the form v1.2.3.4 are now parsed as a string composed of
+Literals of the form C<v1.2.3.4> are now parsed as a string composed of
of characters with the specified ordinals. This is an alternative, more
readable way to construct (possibly unicode) strings instead of
-interpolating characters, as in C<"\x{1}\x{2}\x{3}\x{4}">.
+interpolating characters, as in C<"\x{1}\x{2}\x{3}\x{4}">. The leading
+C<v> may be omitted if there are more than two ordinals, so C<1.2.3> is
+parsed the same as C<v1.2.3>.
Strings written in this form are also useful to represent version "numbers".
It is easy to compare such version "numbers" (which are really just plain
@@ -487,12 +501,17 @@ They will be interpreted as a version rather than as a module name:
require v5.6.0; # croak if $^V lt v5.6.0
use v5.6.0; # same, but croaks at compile-time
+Alternatively, the C<v> may be omitted if there is more than one dot:
+
+ require 5.6.0;
+ use 5.6.0;
+
Also, C<sprintf> and C<printf> support the Perl-specific format flag C<%v>
to print ordinals of characters in arbitrary strings:
printf "v%vd", $^V; # prints current version, such as "v5.5.650"
printf "%*vX", ":", $addr; # formats IPv6 address
- printf "%*vb", "", $bits; # displays bitstring as contiguous 0's and 1's
+ printf "%*vb", " ", $bits; # displays bitstring
See L<perlop/"Strings of Character"> for additional information.
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index f4cee09073..d4215b63f4 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -3551,15 +3551,16 @@ rename(2) manpage or equivalent system documentation for details.
Demands some semantics specified by EXPR, or by C<$_> if EXPR is not
supplied.
-If a VERSION is specified as a literal of the form v5.6.0,
+If a VERSION is specified as a literal of the form v5.6.1,
demands that the current version of Perl (C<$^V> or $PERL_VERSION) be
at least as recent as that version, at run time. (For compatibility
with older versions of Perl, a numeric argument will also be interpreted
as VERSION.) Compare with L</use>, which can do a similar check at
compile time.
- require v5.6.0; # run time version check
- require 5.005_03; # same, number still supported for compatibility
+ require v5.6.1; # run time version check
+ require 5.6.1; # ditto
+ require 5.005_03; # float version allowed for compatibility
Otherwise, demands that a library file be included if it hasn't already
been included. The file is included via the do-FILE mechanism, which is
@@ -4389,7 +4390,7 @@ in arbitrary strings:
printf "version is v%vd\n", $^V; # Perl's version
printf "address is %*vX\n", ":", $addr; # IPv6 address
- printf "bits are %*vb\n", "", $bits; # random bitstring
+ printf "bits are %*vb\n", " ", $bits; # random bitstring
If C<use locale> is in effect, the character used for the decimal
point in formatted real numbers is affected by the LC_NUMERIC locale.
@@ -5255,7 +5256,7 @@ package. It is exactly equivalent to
except that Module I<must> be a bareword.
-VERSION, which can be specified as a literal of the form v5.6.0, demands
+VERSION, which can be specified as a literal of the form v5.6.1, demands
that the current version of Perl (C<$^V> or $PERL_VERSION) be at least
as recent as that version. (For compatibility with older versions of Perl,
a numeric literal will also be interpreted as VERSION.) If the version
@@ -5264,8 +5265,9 @@ message is printed and Perl exits immediately without attempting to
parse the rest of the file. Compare with L</require>, which can do a
similar check at run time.
- use v5.6.0; # compile time version check
- use 5.005_03; # same, number still supported for compatibility
+ use v5.6.1; # compile time version check
+ use 5.6.1; # ditto
+ use 5.005_03; # float version allowed for compatibility
This is often useful if you need to check the current Perl version before
C<use>ing library modules that have changed in incompatible ways from
diff --git a/pod/perlop.pod b/pod/perlop.pod
index 7cb3450032..bc6f2ced40 100644
--- a/pod/perlop.pod
+++ b/pod/perlop.pod
@@ -1811,6 +1811,9 @@ readable interpolation form C<"\x{1}\x{14}\x{12c}\x{fa0}">. This is useful
for representing Unicode strings, and for comparing version "numbers"
using the string comparison operators, C<cmp>, C<gt>, C<lt> etc.
+If there are more than two dots in the literal, the leading C<v> may be
+omitted.
+
Such literals are accepted by both C<require> and C<use> for doing a version
check. The C<$^V> special variable also contains the running Perl
interpreter's version in this form. See L<perlvar/$^V>.
diff --git a/t/comp/require.t b/t/comp/require.t
index cd97c55eda..efce899edc 100755
--- a/t/comp/require.t
+++ b/t/comp/require.t
@@ -47,7 +47,7 @@ eval { require v5.5.630; };
print "# $@\nnot " if $@;
print "ok ",$i++,"\n";
-eval { require v10.0.2; };
+eval { require 10.0.2; };
print "# $@\nnot " unless $@ =~ /^Perl v10\.0\.2 required/;
print "ok ",$i++,"\n";
@@ -55,7 +55,7 @@ eval q{ use v5.5.630; };
print "# $@\nnot " if $@;
print "ok ",$i++,"\n";
-eval q{ use v10.0.2; };
+eval q{ use 10.0.2; };
print "# $@\nnot " unless $@ =~ /^Perl v10\.0\.2 required/;
print "ok ",$i++,"\n";
@@ -75,7 +75,7 @@ eval { require $ver; };
print "# $@\nnot " unless $@ =~ /^Perl v10\.0\.20 required/;
print "ok ",$i++,"\n";
-print "not " unless v5.5.1 gt v5.5;
+print "not " unless 5.5.1 gt v5.5;
print "ok ",$i++,"\n";
{
diff --git a/t/op/ver.t b/t/op/ver.t
index 206b1d08f8..b08849f53a 100755
--- a/t/op/ver.t
+++ b/t/op/ver.t
@@ -5,7 +5,7 @@ BEGIN {
unshift @INC, "../lib";
}
-print "1..18\n";
+print "1..22\n";
my $test = 1;
@@ -35,6 +35,24 @@ print "ok $test\n"; ++$test;
print "not " unless v1.20.300.4000 eq "\x{1}\x{14}\x{12c}\x{fa0}";
print "ok $test\n"; ++$test;
+#
+# now do the same without the "v"
+use 5.5.640;
+require 5.5.640;
+print "ok $test\n"; ++$test;
+
+# hash keys too
+$h{111.107.32} = "ok";
+print "$h{ok } $test\n"; ++$test;
+
+$x = 77.78.79;
+print "not " unless $x eq "MNO";
+print "ok $test\n"; ++$test;
+
+print "not " unless 1.20.300.4000 eq "\x{1}\x{14}\x{12c}\x{fa0}";
+print "ok $test\n"; ++$test;
+
+# test sprintf("%vd"...) etc
print "not " unless sprintf("%vd", "Perl") eq '80.101.114.108';
print "ok $test\n"; ++$test;
@@ -44,7 +62,7 @@ print "ok $test\n"; ++$test;
print "not " unless sprintf("%vx", "Perl") eq '50.65.72.6c';
print "ok $test\n"; ++$test;
-print "not " unless sprintf("%vX", v1.22.333.4444) eq '1.16.14D.115C';
+print "not " unless sprintf("%vX", 1.22.333.4444) eq '1.16.14D.115C';
print "ok $test\n"; ++$test;
print "not " unless sprintf("%*v#o", ":", "Perl") eq '0120:0145:0162:0154';
@@ -60,7 +78,7 @@ print "ok $test\n"; ++$test;
print "ok $test\n"; ++$test;
print "not " unless
- sprintf("%vd", v1.22.333.4444) eq '1.22.197.141.225.133.156';
+ sprintf("%vd", 1.22.333.4444) eq '1.22.197.141.225.133.156';
print "ok $test\n"; ++$test;
print "not " unless sprintf("%vx", "Perl") eq '50.65.72.6c';
diff --git a/toke.c b/toke.c
index a7ceba3546..5347ecd0de 100644
--- a/toke.c
+++ b/toke.c
@@ -821,24 +821,22 @@ STATIC char *
S_force_version(pTHX_ char *s)
{
OP *version = Nullop;
- bool is_vstr = FALSE;
char *d;
s = skipspace(s);
d = s;
- if (*d == 'v') {
- is_vstr = TRUE;
+ if (*d == 'v')
d++;
- }
if (isDIGIT(*d)) {
for (; isDIGIT(*d) || *d == '_' || *d == '.'; d++);
if (*d == ';' || isSPACE(*d) || *d == '}' || !*d) {
+ SV *ver;
s = scan_num(s);
/* real VERSION number -- GBARR */
version = yylval.opval;
- if (is_vstr) {
- SV *ver = cSVOPx(version)->op_sv;
+ ver = cSVOPx(version)->op_sv;
+ if (SvPOK(ver) && !SvNIOK(ver)) {
SvUPGRADE(ver, SVt_PVIV);
SvIOKp_on(ver); /* hint that it is a version */
}
@@ -3499,7 +3497,7 @@ Perl_yylex(pTHX)
char *start = s;
start++;
start++;
- while (isDIGIT(*start))
+ while (isDIGIT(*start) || *start == '_')
start++;
if (*start == '.' && isDIGIT(start[1])) {
s = scan_num(s);
@@ -6886,6 +6884,11 @@ Perl_scan_num(pTHX_ char *start)
if (*s != '_')
*d++ = *s;
}
+ if (*s == '.' && isDIGIT(s[1])) {
+ /* oops, it's really a v-string, but without the "v" */
+ s = start - 1;
+ goto vstring;
+ }
}
/* read exponent part, if present */
@@ -6939,10 +6942,11 @@ Perl_scan_num(pTHX_ char *start)
break;
/* if it starts with a v, it could be a version number */
case 'v':
+vstring:
{
char *pos = s;
pos++;
- while (isDIGIT(*pos))
+ while (isDIGIT(*pos) || *pos == '_')
pos++;
if (!isALPHA(*pos)) {
UV rev;
@@ -6957,7 +6961,23 @@ Perl_scan_num(pTHX_ char *start)
for (;;) {
if (*s == '0' && isDIGIT(s[1]))
yyerror("Octal number in vector unsupported");
- rev = atoi(s);
+ rev = 0;
+ {
+ /* this is atoi() that tolerates underscores */
+ char *end = pos;
+ UV mult = 1;
+ while (--end >= s) {
+ UV orev;
+ if (*end == '_')
+ continue;
+ orev = rev;
+ rev += (*end - '0') * mult;
+ mult *= 10;
+ if (orev > rev && ckWARN_d(WARN_OVERFLOW))
+ Perl_warner(aTHX_ WARN_OVERFLOW,
+ "Integer overflow in decimal number");
+ }
+ }
tmpend = uv_to_utf8(tmpbuf, rev);
utf8 = utf8 || rev > 127;
sv_catpvn(sv, (const char*)tmpbuf, tmpend - tmpbuf);
@@ -6967,7 +6987,7 @@ Perl_scan_num(pTHX_ char *start)
s = pos;
break;
}
- while (isDIGIT(*pos))
+ while (isDIGIT(*pos) || *pos == '_')
pos++;
}