This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Require space between regex and following alnum operator
authorKarl Williamson <public@khwilliamson.com>
Mon, 11 Jun 2012 17:48:04 +0000 (11:48 -0600)
committerKarl Williamson <public@khwilliamson.com>
Mon, 11 Jun 2012 18:21:28 +0000 (12:21 -0600)
Not having such space has been deprecated since v5.14.0.

pod/perldelta.pod
pod/perldiag.pod
pod/perlop.pod
t/lib/warnings/toke
t/re/pat.t
toke.c

index 7980515..fe157fd 100644 (file)
@@ -64,6 +64,21 @@ referred to U+0007, but would raise a deprecated warning.  Now, "BELL"
 refers to U+1F514, and the name for U+0007 is "ALERT".  All the
 functions in L<charnames> have been correspondingly updated.
 
+=head2 Alphanumeric operators must now be separated from the closing
+delimter of regular expressions
+
+You may no longer write something like:
+
+ m/a/and 1
+
+Instead you must write
+
+ m/a/ and 1
+
+with whitespace separating the operator from the closing delimiter of
+the regular expression.  Not having whitespace has resulted in a
+deprecated warning since Perl v5.14.0.
+
 =head1 Deprecations
 
 XXX Any deprecated features, syntax, modules etc. should be listed here.
index 2a486bb..5b5bbdb 100644 (file)
@@ -135,20 +135,6 @@ string C<"-foo">, or a call to the function C<foo>, negated.  If you meant
 the string, just write C<"-foo">.  If you meant the function call,
 write C<-foo()>.
 
-=item Ambiguous use of 's//le...' resolved as 's// le...'; Rewrite as 's//el' if you meant 'use locale rules and evaluate rhs as an expression'.  In Perl 5.18, it will be resolved the other way
-
-(W deprecated, ambiguous) You wrote a pattern match with substitution
-immediately followed by "le".  In Perl 5.16 and earlier, this is
-resolved as meaning to take the result of the substitution, and see if
-it is stringwise less-than-or-equal-to what follows in the expression.
-Having the "le" immediately following a pattern is deprecated behavior,
-so in Perl 5.18, this expression will be resolved as meaning to do the
-pattern match using the rules of the current locale, and evaluate the
-rhs as an expression when doing the substitution.  In 5.14, and 5.16 if
-you want the latter interpretation, you can simply write "el" instead.
-But note that the C</l> modifier should not be used explicitly anyway;
-you should use C<use locale> instead.  See L<perllocale>.
-
 =item '|' and '<' may not both be specified on command line
 
 (F) An error peculiar to VMS.  Perl does its own command line
@@ -2111,27 +2097,6 @@ spots.  This is now heavily deprecated.
 (F) The parser has given up trying to parse the program after 10 errors.
 Further error messages would likely be uninformative.
 
-=item Having no space between pattern and following word is deprecated
-
-(D syntax)
-
-You had a word that isn't a regex modifier immediately following
-a pattern without an intervening space.  If you are trying to use
-the C</le> flags on a substitution, use C</el> instead.  Otherwise, add
-white space between the pattern and following word to eliminate
-the warning.  As an example of the latter, the two constructs:
-
-
- $a =~ m/$foo/sand $bar
- $a =~ m/$foo/s and $bar
-
-both currently mean the same thing, but it is planned to disallow
-the first form in Perl 5.18.  And,
-
- $a =~ m/$foo/and $bar
-
-will be disallowed too.
-
 =item Hexadecimal number > 0xffffffff non-portable
 
 (W portable) The hexadecimal number you specified is larger than 2**32-1
@@ -4999,6 +4964,21 @@ subvert Perl's population of %ENV for nefarious purposes.
 
 (W) You tried to use an unknown subpragma of the "re" pragma.
 
+=item Unknown regex modifier "%s"
+
+(F) Alphanumerics immediately following the closing delimiter
+of a regular expression pattern are interpreted by Perl as modifier
+flags for the regex.  One of the ones you specified is invalid.  One way
+this can happen is if you didn't put in white space between the end of
+the regex and a following alphanumeric operator:
+
+ if ($a =~ /foo/and $bar == 3) { ... }
+
+The C<"a"> is a valid modifier flag, but the C<"n"> is not, and raises
+this error.  Likely what was meant instead was:
+
+ if ($a =~ /foo/ and $bar == 3) { ... }
+
 =item Unknown switch condition (?(%s in regex; marked by <-- HERE in m/%s/
 
 (F) The condition part of a (?(condition)if-clause|else-clause) construct
index 7b2d0a3..a53f869 100644 (file)
@@ -2068,14 +2068,6 @@ to occur that you might want.  Here are two common cases:
     # expand tabs to 8-column spacing
     1 while s/\t+/' ' x (length($&)*8 - length($`)%8)/e;
 
-C<s///le> is treated as a substitution followed by the C<le> operator, not
-the C</le> flags.  This may change in a future version of Perl.  It
-produces a warning if warnings are enabled.  To disambiguate, use a space
-or change the order of the flags:
-
-    s/foo/bar/ le 5;  # "le" infix operator
-    s/foo/bar/el;     # "e" and "l" flags
-
 =back
 
 =head2 Quote-Like Operators
index a9106fb..db4bbee 100644 (file)
@@ -143,19 +143,24 @@ Use of comma-less variable list is deprecated at - line 4.
 Use of comma-less variable list is deprecated at - line 4.
 ########
 # toke.c
-$a =~ m/$foo/sand $bar;
-$a =~ s/$foo/fool/sand $bar;
 $a = <<;
 
 no warnings 'deprecated' ;
-$a =~ m/$foo/sand $bar;
-$a =~ s/$foo/fool/sand $bar;
 $a = <<;
 
 EXPECT
-Having no space between pattern and following word is deprecated at - line 2.
-Having no space between pattern and following word is deprecated at - line 3.
-Use of bare << to mean <<"" is deprecated at - line 4.
+Use of bare << to mean <<"" is deprecated at - line 2.
+########
+# toke.c
+$a =~ m/$foo/eq;
+$a =~ s/$foo/fool/seq;
+
+EXPECT
+OPTION fatal
+Unknown regexp modifier "/e" at - line 2, near "=~ "
+Unknown regexp modifier "/q" at - line 2, near "=~ "
+Unknown regexp modifier "/q" at - line 3, near "=~ "
+Execution of - aborted due to compilation errors.
 ########
 # toke.c
 use warnings 'syntax' ;
index 9c29c95..e03f5ca 100644 (file)
@@ -19,7 +19,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan tests => 474;  # Update this when adding/deleting tests.
+plan tests => 436;  # Update this when adding/deleting tests.
 
 run_tests() unless caller;
 
@@ -1069,51 +1069,6 @@ sub run_tests {
     }
 
     {
-        # Test that a regex followed by an operator and/or a statement modifier work
-        # These tests use string-eval so that it reports a clean error when it fails
-        # (without the string eval the test script might be unparseable)
-
-        # Note: these test check the behaviour that currently is valid syntax
-        # If a new regex modifier is added and a test fails then there is a backwards-compatibility issue
-        # Note-2: a new deprecate warning was added for this with commit e6897b1a5db0410e387ccbf677e89fc4a1d8c97a
-        # which indicate that this syntax will be removed in 5.16.
-        # When this happens the tests can be removed
-
-       foreach (['my $r = "a" =~ m/a/lt 2', 'm', 'lt'],
-                ['my $r = "a" =~ m/a/le 1', 'm', 'le'],
-                ['my $r = "a" =~ m/a/eq 1', 'm', 'eq'],
-                ['my $r = "a" =~ m/a/ne 0', 'm', 'ne'],
-                ['my $r = "a" =~ m/a/and 1', 'm', 'and'],
-                ['my $r = "a" =~ m/a/unless 0', 'm', 'unless'],
-                ['my $c = 1; my $r; $r = "a" =~ m/a/while $c--', 'm', 'while'],
-                ['my $c = 0; my $r; $r = "a" =~ m/a/until $c++', 'm', 'until'],
-                ['my $r; $r = "a" =~ m/a/for 1', 'm', 'for'],
-                ['my $r; $r = "a" =~ m/a/foreach 1', 'm', 'foreach'],
-
-                ['my $t = "a"; my $r = $t =~ s/a//lt 2', 's', 'lt'],
-                ['my $t = "a"; my $r = $t =~ s/a//le 1', 's', 'le'],
-                ['my $t = "a"; my $r = $t =~ s/a//ne 0', 's', 'ne'],
-                ['my $t = "a"; my $r = $t =~ s/a//and 1', 's', 'and'],
-                ['my $t = "a"; my $r = $t =~ s/a//unless 0', 's', 'unless'],
-
-                ['my $c = 1; my $r; my $t = "a"; $r = $t =~ s/a//while $c--', 's', 'while'],
-                ['my $c = 0; my $r; my $t = "a"; $r = $t =~ s/a//until $c++', 's', 'until'],
-                ['my $r; my $t = "a"; $r = $t =~ s/a//for 1', 's', 'for'],
-                ['my $r; my $t = "a"; $r = $t =~ s/a//for 1', 's', 'foreach'],
-               ) {
-           my $message = sprintf 'regex (%s) followed by $_->[2]',
-               $_->[1] eq 'm' ? 'm//' : 's///';
-           my $code = "$_->[0]; 'eval_ok ' . \$r";
-           my $result = do {
-               no warnings 'syntax';
-               eval $code;
-           };
-           is($@, '', $message);
-           is($result, 'eval_ok 1', $message);
-       }
-    }
-
-    {
         my $str= "\x{100}";
         chop $str;
         my $qr= qr/$str/;
diff --git a/toke.c b/toke.c
index 0d5e321..6079817 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -9014,13 +9014,15 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse
      * current regex.  This routine will set it to any charset modifier found.
      * The caller shouldn't change it.  This way, another charset modifier
      * encountered in the parse can be detected as an error, as we have decided
-     * allow only one */
+     * to allow only one */
 
     const char c = **s;
 
     if (! strchr(valid_flags, c)) {
         if (isALNUM(c)) {
-           goto deprecate;
+           yyerror(Perl_form(aTHX_ "Unknown regexp modifier \"/%c\"", c));
+            (*s)++;
+            return TRUE;
         }
         return FALSE;
     }
@@ -9034,34 +9036,6 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse
         case KEEPCOPY_PAT_MOD:    *pmfl |= RXf_PMf_KEEPCOPY; break;
         case NONDESTRUCT_PAT_MOD: *pmfl |= PMf_NONDESTRUCT; break;
        case LOCALE_PAT_MOD:
-
-           /* In 5.14, qr//lt is legal but deprecated; the 't' means they
-            * can't be regex modifiers.
-            * In 5.14, s///le is legal and ambiguous.  Try to disambiguate as
-            * much as easily done.  s///lei, for example, has to mean regex
-            * modifiers if it's not an error (as does any word character
-            * following the 'e').  Otherwise, we resolve to the backwards-
-            * compatible, but less likely 's/// le ...', i.e. as meaning
-            * less-than-or-equal.  The reason it's not likely is that s//
-            * returns a number for code in the field (/r returns a string, but
-            * that wasn't added until the 5.13 series), and so '<=' should be
-            * used for comparing, not 'le'. */
-           if (*((*s) + 1) == 't') {
-               goto deprecate;
-           }
-           else if (*((*s) + 1) == 'e' && ! isALNUM(*((*s) + 2))) {
-
-               /* 'e' is valid only for substitutes, s///e.  If it is not
-                * valid in the current context, then 'm//le' must mean the
-                * comparison operator, so use the regular deprecation message.
-                */
-               if (! strchr(valid_flags, 'e')) {
-                   goto deprecate;
-               }
-               Perl_ck_warner_d(aTHX_ packWARN(WARN_AMBIGUOUS),
-                   "Ambiguous use of 's//le...' resolved as 's// le...'; Rewrite as 's//el' if you meant 'use locale rules and evaluate rhs as an expression'.  In Perl 5.18, it will be resolved the other way");
-               return FALSE;
-           }
            if (*charset) {
                goto multiple_charsets;
            }
@@ -9069,11 +9043,6 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse
            *charset = c;
            break;
        case UNICODE_PAT_MOD:
-           /* In 5.14, qr//unless and qr//until are legal but deprecated; the
-            * 'n' means they can't be regex modifiers */
-           if (*((*s) + 1) == 'n') {
-               goto deprecate;
-           }
            if (*charset) {
                goto multiple_charsets;
            }
@@ -9081,12 +9050,6 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse
            *charset = c;
            break;
        case ASCII_RESTRICT_PAT_MOD:
-           /* In 5.14, qr//and is legal but deprecated; the 'n' means they
-            * can't be regex modifiers */
-           if (*((*s) + 1) == 'n') {
-               goto deprecate;
-           }
-
            if (! *charset) {
                set_regex_charset(pmfl, REGEX_ASCII_RESTRICTED_CHARSET);
            }
@@ -9116,11 +9079,6 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse
     (*s)++;
     return TRUE;
 
-    deprecate:
-       Perl_ck_warner_d(aTHX_ packWARN(WARN_SYNTAX),
-           "Having no space between pattern and following word is deprecated");
-        return FALSE;
-
     multiple_charsets:
        if (*charset != c) {
            yyerror(Perl_form(aTHX_ "Regexp modifiers \"/%c\" and \"/%c\" are mutually exclusive", *charset, c));