make qw() into a true list at compile time (slightly modified
Gurusamy Sarathy [Mon, 8 Feb 1999 14:40:23 +0000 (14:40 +0000)]
variant of patch suggested by Tom Hughes <tom@compton.demon.co.uk>)

p4raw-id: //depot/perl@2835

pod/perldelta.pod
pod/perlop.pod
pp_hot.c
toke.c

index b2e197f..0de44db 100644 (file)
@@ -107,6 +107,11 @@ behavior of:
 
 remains unchanged.  See L<perlop>.
 
+=item Improved C<qw//> operator
+
+The C<qw//> operator is now evaluated at compile time instead of being
+replaced with a run time call to C<split()>.
+
 =head1 Supported Platforms
 
 =over 4
index 0b848ad..4b49808 100644 (file)
@@ -1040,13 +1040,13 @@ See L<"I/O Operators"> for more discussion.
 
 =item qw/STRING/
 
-Returns a list of the words extracted out of STRING, using embedded
-whitespace as the word delimiters.  It is exactly equivalent to
+Evaluates to a list of the words extracted out of STRING, using embedded
+whitespace as the word delimiters.  It can be understood as being roughly
+equivalent to:
 
     split(' ', q/STRING/);
 
-This equivalency means that if used in scalar context, you'll get split's
-(unfortunate) scalar context behavior, complete with mysterious warnings.
+the difference being that it generates a real list at compile time.
 
 Some frequently seen examples:
 
index 98763b8..f304e8b 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -655,7 +655,7 @@ PP(pp_aassign)
                    if (SvSMAGICAL(sv))
                        mg_set(sv);
                    if (!didstore)
-                       SvREFCNT_dec(sv);
+                       sv_2mortal(sv);
                }
                TAINT_NOT;
            }
@@ -682,7 +682,7 @@ PP(pp_aassign)
                        if (SvSMAGICAL(tmpstr))
                            mg_set(tmpstr);
                        if (!didstore)
-                           SvREFCNT_dec(tmpstr);
+                           sv_2mortal(tmpstr);
                    }
                    TAINT_NOT;
                }
@@ -704,7 +704,7 @@ PP(pp_aassign)
                            if (SvSMAGICAL(tmpstr))
                                mg_set(tmpstr);
                            if (!didstore)
-                               SvREFCNT_dec(tmpstr);
+                               sv_2mortal(tmpstr);
                        }
                        TAINT_NOT;
                    }
diff --git a/toke.c b/toke.c
index 22344b4..4ab20c2 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -3838,36 +3838,46 @@ int yylex(PERL_YYLEX_PARAM_DECL)
            s = scan_str(s);
            if (!s)
                missingterm((char*)0);
-           if (ckWARN(WARN_SYNTAX) && SvLEN(PL_lex_stuff)) {
+           force_next(')');
+           if (SvCUR(PL_lex_stuff)) {
+               OP *words = Nullop;
+               int warned = 0;
                d = SvPV_force(PL_lex_stuff, len);
-               for (; len; --len, ++d) {
-                   if (*d == ',') {
-                       warner(WARN_SYNTAX,
-                           "Possible attempt to separate words with commas");
-                       break;
-                   }
-                   if (*d == '#') {
-                       warner(WARN_SYNTAX,
-                           "Possible attempt to put comments in qw() list");
-                       break;
+               while (len) {
+                   for (; isSPACE(*d) && len; --len, ++d) ;
+                   if (len) {
+                       char *b = d;
+                       if (!warned && ckWARN(WARN_SYNTAX)) {
+                           for (; !isSPACE(*d) && len; --len, ++d) {
+                               if (*d == ',') {
+                                   warner(WARN_SYNTAX,
+                                       "Possible attempt to separate words with commas");
+                                   ++warned;
+                               }
+                               else if (*d == '#') {
+                                   warner(WARN_SYNTAX,
+                                       "Possible attempt to put comments in qw() list");
+                                   ++warned;
+                               }
+                           }
+                       }
+                       else {
+                           for (; !isSPACE(*d) && len; --len, ++d) ;
+                       }
+                       words = append_elem(OP_LIST, words,
+                                           newSVOP(OP_CONST, 0, newSVpvn(b, d-b)));
                    }
                }
+               if (words) {
+                   PL_nextval[PL_nexttoke].opval = words;
+                   force_next(THING);
+               }
            }
-           force_next(')');
-           PL_nextval[PL_nexttoke].opval = (OP*)newSVOP(OP_CONST, 0, tokeq(PL_lex_stuff));
+           if (PL_lex_stuff)
+               SvREFCNT_dec(PL_lex_stuff);
            PL_lex_stuff = Nullsv;
-           force_next(THING);
-           force_next(',');
-           PL_nextval[PL_nexttoke].opval = (OP*)newSVOP(OP_CONST, 0, newSVpv(" ",1));
-           force_next(THING);
-           force_next('(');
-           yylval.ival = OP_SPLIT;
-           CLINE;
            PL_expect = XTERM;
-           PL_bufptr = s;
-           PL_last_lop = PL_oldbufptr;
-           PL_last_lop_op = OP_SPLIT;
-           return FUNC;
+           TOKEN('(');
 
        case KEY_qq:
            s = scan_str(s);