Front page | perl.perl5.porters |
Postings from April 2010
[PATCH 2/3] deprecate alphanumerics immediately after number
From:
Zefram
Date:
April 24, 2010 01:28
Subject:
[PATCH 2/3] deprecate alphanumerics immediately after number
Message ID:
ae2f09fcc71a8c647172aa41db0d55d0f18635a32.1272045026.git.zefram@fysh.org
"print$_+1foreach$x,$y" and "$x=1if$y" are legal, despite mashing together
a numeric literal with a keyword. (If the number is changed to hex,
the latter still works but the former becomes a syntax error, due to
the accident of which letter the keywords start with.) This severely
restricts the options for adding new numeric syntax in the future, such as
"0o123" for octal, and yields poor error messages when done by accident.
This change deprecates these situations.
---
MANIFEST | 2 +-
pod/perldiag.pod | 11 +++++++++
t/comp/binary_num.t | 36 ------------------------------
t/comp/deprecated_num.t | 55 +++++++++++++++++++++++++++++++++++++++++++++++
t/op/attrs.t | 6 +++-
toke.c | 4 +++
6 files changed, 75 insertions(+), 39 deletions(-)
delete mode 100644 t/comp/binary_num.t
create mode 100644 t/comp/deprecated_num.t
diff --git a/MANIFEST b/MANIFEST
index d9b7287..f0b927e 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -4190,11 +4190,11 @@ t/cmd/mod.t See if statement modifiers work
t/cmd/subval.t See if subroutine values work
t/cmd/switch.t See if switch optimizations work
t/cmd/while.t See if while loops work
-t/comp/binary_num.t See if bin/oct/hex numbers are parsed right
t/comp/bproto.t See if builtins conform to their prototypes
t/comp/cmdopt.t See if command optimization works
t/comp/colon.t See if colons are parsed correctly
t/comp/decl.t See if declarations work
+t/comp/deprecated_num.t See if deprecated numbers warn right
t/comp/final_line_num.t See if line numbers are correct at EOF
t/comp/fold.t See if constant folding works
t/comp/form_scope.t See if format scoping works
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index fb6aca2..bd1f30d 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -4976,6 +4976,17 @@ hexadecimal, octal, and binary literals. If you want concatenation,
either add spaces (C<0xa . 8>) or wrap one of the numbers in parentheses
(C<(0xa).8>).
+=item Use of keyword immediately after number is deprecated
+
+(D deprecated, syntax) Source such as C<123wibble> is interpreted as a
+number followed by a bareword. This can appear in a legal program if
+the bareword is a keyword, such as in C<$x=1if$y>. This interpretation
+is deprecated, so that in the future we can make the error messages
+less confusing when this is done by accident, and to open the way for
+new numeric syntax involving letters appearing in a token that starts
+with digits. If correct code triggers this warning, add a space between
+the number and the keyword.
+
=item Use of reference "%s" as array index
(W misc) You tried to use a reference as an array index; this probably
diff --git a/t/comp/binary_num.t b/t/comp/binary_num.t
deleted file mode 100644
index daf0a9f..0000000
--- a/t/comp/binary_num.t
+++ /dev/null
@@ -1,36 +0,0 @@
-#!./perl
-
-print "1..30\n";
-my $test_num = 0;
-sub ok {
- print $_[0] ? "" : "not ", "ok ", ++$test_num, "\n";
-}
-
-sub do_test {
- my($src, $expect_value, $match_warning) = @_;
- my($value, $warning);
- local $SIG{__WARN__} = sub { $warning .= $_[0] };
- $value = eval($src);
- ok defined($expect_value) ? $value == $expect_value : !defined($value);
- ok $warning =~ $match_warning;
-}
-
-do_test "0x123", 291, qr/\A\z/;
-do_test "0x123.8", 2918, qr/\AUse of \. immediately after hexadecimal number/;
-do_test "0x123 .8", 2918, qr/\A\z/;
-do_test "0x123. 8", 2918, qr/\AUse of \. immediately after hexadecimal number/;
-do_test "[0x123..8] && 5", 5, qr/\A\z/;
-
-do_test "0123", 83, qr/\A\z/;
-do_test "0123.4", 834, qr/\AUse of \. immediately after octal number/;
-do_test "0123 .4", 834, qr/\A\z/;
-do_test "0123. 4", 834, qr/\AUse of \. immediately after octal number/;
-do_test "[0123..4] && 5", 5, qr/\A\z/;
-
-do_test "0b101", 5, qr/\A\z/;
-do_test "0b101.1", 51, qr/\AUse of \. immediately after binary number/;
-do_test "0b101 .1", 51, qr/\A\z/;
-do_test "0b101. 1", 51, qr/\AUse of \. immediately after binary number/;
-do_test "[0b101..1] && 5", 5, qr/\A\z/;
-
-1;
diff --git a/t/comp/deprecated_num.t b/t/comp/deprecated_num.t
new file mode 100644
index 0000000..2bae8e3
--- /dev/null
+++ b/t/comp/deprecated_num.t
@@ -0,0 +1,55 @@
+#!./perl
+
+print "1..54\n";
+my $test_num = 0;
+sub ok {
+ print $_[0] ? "" : "not ", "ok ", ++$test_num, "\n";
+}
+
+sub do_test {
+ my($src, $expect_value, $match_warning) = @_;
+ my($value, $warning);
+ local $SIG{__WARN__} = sub { $warning .= $_[0] };
+ $value = eval($src);
+ ok defined($expect_value) ? $value == $expect_value : !defined($value);
+ ok $warning =~ $match_warning;
+}
+
+do_test "0x123", 291, qr/\A\z/;
+do_test "0x123.8", 2918, qr/\AUse of \. immediately after hexadecimal number/;
+do_test "0x123 .8", 2918, qr/\A\z/;
+do_test "0x123. 8", 2918, qr/\AUse of \. immediately after hexadecimal number/;
+do_test "[0x123..8] && 5", 5, qr/\A\z/;
+
+do_test "0123", 83, qr/\A\z/;
+do_test "0123.4", 834, qr/\AUse of \. immediately after octal number/;
+do_test "0123 .4", 834, qr/\A\z/;
+do_test "0123. 4", 834, qr/\AUse of \. immediately after octal number/;
+do_test "[0123..4] && 5", 5, qr/\A\z/;
+
+do_test "0b101", 5, qr/\A\z/;
+do_test "0b101.1", 51, qr/\AUse of \. immediately after binary number/;
+do_test "0b101 .1", 51, qr/\A\z/;
+do_test "0b101. 1", 51, qr/\AUse of \. immediately after binary number/;
+do_test "[0b101..1] && 5", 5, qr/\A\z/;
+
+do_test q{ my $x = 11; $x = 22 if 1; $x }, 22, qr/\A\z/;
+do_test q{ my $x = 11; $x = 22if 1; $x }, 22,
+ qr/\AUse of keyword immediately after number/;
+do_test q{ my $x = 11.11; $x = 22.22 if 1; $x }, 22.22, qr/\A\z/;
+do_test q{ my $x = 11.11; $x = 22.22if 1; $x }, 22.22,
+ qr/\AUse of keyword immediately after number/;
+do_test q{ my $x = 11e11; $x = 22e22 if 1; $x }, 22e22, qr/\A\z/;
+do_test q{ my $x = 11e11; $x = 22e22if 1; $x }, 22e22,
+ qr/\AUse of keyword immediately after number/;
+do_test q{ my $x = 0x11; $x = 0x22 if 1; $x }, 34, qr/\A\z/;
+do_test q{ my $x = 0x11; $x = 0x22if 1; $x }, 34,
+ qr/\AUse of keyword immediately after number/;
+do_test q{ my $x = 011; $x = 022 if 1; $x }, 18, qr/\A\z/;
+do_test q{ my $x = 011; $x = 022if 1; $x }, 18,
+ qr/\AUse of keyword immediately after number/;
+do_test q{ my $x = 0b11; $x = 0b101 if 1; $x }, 5, qr/\A\z/;
+do_test q{ my $x = 0b11; $x = 0b101if 1; $x }, 5,
+ qr/\AUse of keyword immediately after number/;
+
+1;
diff --git a/t/op/attrs.t b/t/op/attrs.t
index 7c98529..5aaf366 100644
--- a/t/op/attrs.t
+++ b/t/op/attrs.t
@@ -14,7 +14,7 @@ BEGIN {
use warnings;
-plan 92;
+plan 93;
$SIG{__WARN__} = sub { die @_ };
@@ -69,7 +69,9 @@ eval 'my $x : switch(10,foo();';
like $@, qr/^Unterminated attribute parameter in attribute list at/;
eval q/my $x : Ugly('(');/;
like $@, qr/^Unterminated attribute parameter in attribute list at/;
-eval 'my $x : 5x5;';
+eval 'my $x : 555;';
+like $@, qr/error/;
+eval 'no warnings qw(deprecated syntax); my $x : 5x5;';
like $@, qr/error/;
eval 'my $x : Y2::north;';
like $@, qr/Invalid separator character ':' in attribute list at/;
diff --git a/toke.c b/toke.c
index 1f8f8e3..775824a 100644
--- a/toke.c
+++ b/toke.c
@@ -13321,6 +13321,10 @@ vstring:
break;
}
+ if (isALNUM(*s))
+ Perl_ck_warner_d(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
+ "Use of keyword immediately after number is deprecated");
+
/* make the op for the constant and return */
if (sv)
--
1.5.6.5
-
[PATCH 2/3] deprecate alphanumerics immediately after number
by Zefram