develooper Front page | perl.perl5.porters | Postings from April 2003

Re: [PATCH] [perl #21875] Hash ref transformed as a list

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
April 19, 2003 12:06
Subject:
Re: [PATCH] [perl #21875] Hash ref transformed as a list
Message ID:
20030419190651.GD13333@fdgroup.com
On Wed, Apr 09, 2003 at 01:27:44PM +0200, Rafael Garcia-Suarez wrote:
> Dave Mitchell wrote:
> > 
> > Ah yes, a test case - how silly of me to forget ...
> > 
> > My patch just fixes the
> > 
> >     { bareword_starting_with_q =>
> > 
> > case, it doesnt fix the
> > 
> >     { q =>
> > 
> > case, since while the first is clearly a bug, the second may (or may
> > not) be a feature, since that could legitimately be a q=string= quoting
> > construct. Ie it skips to the matching = as being the end of the term,
> > then fails to see a following comma or =>, so assumes it's not a hash.  I
> > could update the patch to treat /{\s*q[qx]?\s+=>/ as a special case if
> > people want. Also, I notice that it doesn't check for qw and qr.  Should I
> > add these?
> 
> Uh, if it handles qq and qx, I think it should handle qw and qr as well.
> (I haven't looked closely at this.)

On further reflection, I don't think it should. neither qw or qr are
normally found as the first key term of a { foo => ... } hash constructor.

> 
> > Finally, where should the test go? t/op/parser.t ??
> 
> Almost, t/comp/parser.t

Okay, here's a revised patch that handled plain { q => ...}, plus some
tests


-- 
O Unicef Clearasil!
Gibberish and Drivel!
                      - "Bored of the Rings"


--- toke.c-	Sat Apr 19 20:00:32 2003
+++ toke.c	Sat Apr 19 19:56:05 2003
@@ -3211,12 +3211,17 @@ Perl_yylex(pTHX)
 			    || ((*t == 'q' || *t == 'x') && ++t < PL_bufend
 				&& !isALNUM(*t))))
 		    {
+			/* skip q//-like construct */
 			char *tmps;
 			char open, close, term;
 			I32 brackets = 1;
 
 			while (t < PL_bufend && isSPACE(*t))
 			    t++;
+			/* check for q => */
+			if (t+1 < PL_bufend && t[0] == '=' && t[1] == '>') {
+			    OPERATOR(HASHBRACK);
+			}
 			term = *t;
 			open = term;
 			if (term && (tmps = strchr("([{< )]}> )]}>",term)))
@@ -3229,7 +3234,7 @@ Perl_yylex(pTHX)
 				else if (*t == open)
 				    break;
 			    }
-			else
+			else {
 			    for (t++; t < PL_bufend; t++) {
 				if (*t == '\\' && t+1 < PL_bufend)
 				    t++;
@@ -3238,8 +3243,13 @@ Perl_yylex(pTHX)
 				else if (*t == open)
 				    brackets++;
 			    }
+			}
+			t++;
 		    }
-		    t++;
+		    else
+			/* skip plain q word */
+			while (t < PL_bufend && isALNUM_lazy_if(t,UTF))
+			     t += UTF8SKIP(t);
 		}
 		else if (isALNUM_lazy_if(t,UTF)) {
 		    t += UTF8SKIP(t);
--- t/comp/parser.t-	Sat Apr 19 20:01:05 2003
+++ t/comp/parser.t	Sat Apr 19 20:02:15 2003
@@ -9,7 +9,7 @@
 }
 
 require "./test.pl";
-plan( tests => 21 );
+plan( tests => 37 );
 
 eval '%@x=0;';
 like( $@, qr/^Can't modify hash dereference in repeat \(x\)/, '%@x=0' );
@@ -97,3 +97,23 @@
 print(
 $data{foo});
 pass();
+
+# Bug #21875
+# { q.* => ... } should be interpreted as hash, not block
+
+foreach my $line (split /\n/, <<'EOF')
+1 { foo => 'bar' }
+1 { qoo => 'bar' }
+1 { q   => 'bar' }
+1 { qq  => 'bar' }
+0 { q,'bar', }
+0 { q=bar= }
+0 { qq=bar= }
+1 { q=bar= => 'bar' }
+EOF
+{
+    my ($expect, $eval) = split / /, $line, 2;
+    my $result = eval $eval;
+    ok($@ eq  '', "eval $eval");
+    is(ref $result, $expect ? 'HASH' : '', $eval);
+}

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About