Closed p5pRT closed 20 years ago
I was trying to do %hash = map { "\L$_"\, 1 } @array but it appears that any construct of the form: map { "string"\, 1 } causes a syntax error. I have found a work around for this: map { ("\L$_"\, 1) } @array
This is also broken in 5.005.03.
On Fri\, Nov 17\, 2000 at 11:01:07AM -0600\, Bruce Albrecht wrote:
I was trying to do %hash = map { "\L$_"\, 1 } @array but it appears that any construct of the form: map { "string"\, 1 } causes a syntax error. I have found a work around for this: map { ("\L$_"\, 1) } @array
Thank you for your report. This is actually a known issue.
With the advent of anonymous hash references\, Perl has to determine whether map { ... is the start of map BLOCK LIST\, or map EXPR\, LIST with an anonymous hash as the expression.
Because Perl doesn't look ahead to the closing brace\, it has to guess. If the opening brace is followed by a string and a comma\, Perl guesses that it is an anonymous hash. Perl then expects to find a comma after the closing brace\, and reports a syntax error if there isn't one.
One workaround is to use parens\, as you found. Another is to put a plus before the string.
Because the workarounds are so simple\, this bug does not have a high priority for being fixed.
Ronald
Lightning flashed\, thunder crashed and Ronald J Kimball \<rjk@linguist.dartmouth .edu> whispered: | On Fri\, Nov 17\, 2000 at 11:01:07AM -0600\, Bruce Albrecht wrote: |
---|---|
> I was trying to do | |
> %hash = map { "\L$_"\, 1 } @array | |
> but it appears that any construct of the form: | |
> map { "string"\, 1 } | |
> causes a syntax error. I have found a work around for this: | |
> map { ("\L$_"\, 1) } @array | |
Thank you for your report. This is actually a known issue. |
Another fix for this specific instance is to use lc($_) instead of "\L$_".
-spp
On Fri\, Nov 17\, 2000 at 01:27:52PM -0500\, Stephen P. Potter wrote:
Lightning flashed\, thunder crashed and Ronald J Kimball \<rjk@linguist.dartmouth .edu> whispered: On Fri\, Nov 17\, 2000 at 11:01:07AM -0600\, Bruce Albrecht wrote: > I was trying to do > %hash = map { "\L$_"\, 1 } @array > but it appears that any construct of the form: > map { "string"\, 1 } > causes a syntax error. I have found a work around for this: > map { ("\L$_"\, 1) } @array Thank you for your report. This is actually a known issue. Another fix for this specific instance is to use lc($_) instead of "\L$_".
but currently it's not documented as a trap. maybe I went a bit over the top:
*** pod/perlfunc.pod.orig Tue Nov 14 18:56:07 2000
--- pod/perlfunc.pod Fri Nov 17 20:55:37 2000
***************
*** 2483\,2488 ****
--- 2483\,2511 ----
most cases. See also L\ for an array composed of those items of
the original list for which the BLOCK or EXPR evaluates to true.
+ C\<{> starts both hash references and blocks\, so C\<map { ...> could be either
+ the start of map BLOCK LIST or map EXPR\, LIST. Because perl doesn't look
+ ahead for the closing C\<}> it has to take a guess at which its dealing with
+ based what it finds just after the C\<{>. Usually it gets it right\, but if it
+ doesn't it won't realize something is wrong until it gets to the C\<}> and
+ encounters the missing (or unexpected) comma. The syntax error will be
+ reported close to the C\<}> but you'll need to change something near the C\<{>
+ such as using a unary C\<+> to give perl some help:
+
+ %hash = map { "\L$_"\, 1 } @array # perl guesses EXPR. wrong
+ %hash = map { +"\L$_"\, 1 } @array # perl guesses BLOCK. right
+ %hash = map { ("\L$_"\, 1) } @array # this also works
+ %hash = map { lc($_)\, 1 } @array # as does this.
+ %hash = map +( lc($_)\, 1 )\, @array # this is EXPR and works!
+
+ %hash = map ( lc($_)\, 1 )\, @array # evaluates to (1\, @array)
+
+ or to force an anon hash constructor use C\<+{>
+
+ @hashes = map +{ lc($_)\, 1 }\, @array # EXPR\, so needs \, at end
+
+ and you get list of anonymous hashes each with only 1 entry.
+
=item mkdir FILENAME\,MASK
=item mkdir FILENAME
map(lc($_)\,1)\,@foo versus map+(lc($_)\,1)\,@foo starts to look like something for an obfuscated perl contest.
Nicholas Clark
On Fri\, Nov 17\, 2000 at 10:10:28PM +0000\, Nicholas Clark wrote:
On Fri\, Nov 17\, 2000 at 01:27:52PM -0500\, Stephen P. Potter wrote:
Lightning flashed\, thunder crashed and Ronald J Kimball \<rjk@linguist.dartmouth .edu> whispered: On Fri\, Nov 17\, 2000 at 11:01:07AM -0600\, Bruce Albrecht wrote: > I was trying to do > %hash = map { "\L$_"\, 1 } @array > but it appears that any construct of the form: > map { "string"\, 1 } > causes a syntax error. I have found a work around for this: > map { ("\L$_"\, 1) } @array Thank you for your report. This is actually a known issue. Another fix for this specific instance is to use lc($_) instead of "\L$_".
but currently it's not documented as a trap. maybe I went a bit over the top:
Applied\, thanks.
In article \20001117221028\.A88930@​plum\.flirble\.org\, Nicholas Clark \nick@​ccl4\.org wrote:
+ C\<{> starts both hash references and blocks\, so C\<map { ...> could be either + the start of map BLOCK LIST or map EXPR\, LIST. Because perl doesn't look + ahead for the closing C\<}> it has to take a guess at which its dealing with + based what it finds just after the C\<{>. Usually it gets it right\, but if it + doesn't it won't realize something is wrong until it gets to the C\<}> and + encounters the missing (or unexpected) comma. The syntax error will be + reported close to the C\<}> but you'll need to change something near the C\<{> + such as using a unary C\<+> to give perl some help: + + %hash = map { "\L$_"\, 1 } @array # perl guesses EXPR. wrong + %hash = map { +"\L$_"\, 1 } @array # perl guesses BLOCK. right + %hash = map { ("\L$_"\, 1) } @array # this also works + %hash = map { lc($_)\, 1 } @array # as does this. + %hash = map +( lc($_)\, 1 )\, @array # this is EXPR and works!
You left out my favorite!
On Sun\, Nov 19\, 2000 at 12:13:57PM -0800\, Yitzchak Scott-Thoennes wrote:
You left out my favorite!
--- pod/perlfunc.pod.orig Sat Nov 18 22:49:02 2000 +++ pod/perlfunc.pod Sun Nov 19 12:11:24 2000 @@ -2495\,7 +2495\,8 @@ %hash = map { "\L$_"\, 1 } @array # perl guesses EXPR. wrong %hash = map { +"\L$_"\, 1 } @array # perl guesses BLOCK. right %hash = map { ("\L$_"\, 1) } @array # this also works - %hash = map { lc($_)\, 1 } @array # as does this. + %hash = map { lc($_)\, 1 } @array # as does this + %hash = map {; "\L$_"\, 1 } @array # and this.
that's quite nifty :-)
%hash = map \+\( lc\($\_\)\, 1 \)\, @​array \# this is EXPR and works\!
I also verified (after inspecting the code in toke.c) that having a literal newline inside the "" string also makes it look not like-an-anon-hash (the sniffer code looks to pair the qq() and find a "\," or => all as lookahead in the current line. Embedded literal \n means the close of the q() isn't in the current buffer\, so the {} is treated as block. Interesting only in that it's actually a case of whitespace having syntactic significance (sort of. arguably characters in strings are not "whitespace" in the traditional sense).
Nicholas Clark
Migrated from rt.perl.org#4723 (status was 'resolved')
Searchable as RT4723$