note
tlm
<p>The unary operator <tt>+</tt> is often used to disambiguate syntax that would otherwise confuse perl. In the case of <tt>map</tt> this can happen in two different situations. One is when the first non-whitespace character after the <tt>map</tt> keyword is a <tt>(</tt>. The other one is when this character is a <tt>{</tt> ...</p>
<readmore>
<p>In the case of a "<tt>(</tt>" perl can't tell whether this parenthesis signals the opening of the argument list for <tt>map</tt> or it is being used merely to group the expressions in the first argument of <tt>map</tt>. Consider this:
<c>
my %hash = map ( $_ => 1 ), @array;
</c>
perl will interpret this as
<c>
(my %hash = map( $_, 1 )), @array;
</c>
which is not the desired intent. A simple way to clue perl in is to put a <tt>+</tt> before the "<tt>(</tt>"<sup>1</sup>:
<c>
my %hash = map +( $_ => 1 ), @array;
</c>
BTW, the line above is a common way to "hashify" an array.</p>
<p>
Another common situation when you will see the same trick is with <tt>print</tt>:
<c>
print +( $x ? $y : $z ), "\n";
</c>
Without the <tt>+</tt>, the above would be interpreted as
<c>
(print( $x ? $y : $z )), "\n";
</c>
</p>
<p>The second potentially ambiguous situation with <tt>map</tt> is when the first character after the <tt>map</tt> keyword is a <tt>{</tt>, because it could either refer to a block or to an anonymous hash. I saw this (admittedly farfetched) example recently:
<c>
my @foo = map { 1, 2 } 3, 4;
</c>
which triggers a syntax error, even though it is syntactically correct. Instead of "hmm, no comma after the <tt>}</tt>; it must be a block then", perl opts for "hmm, no comma after the <tt>}</tt>; SYNTAX ERROR!" Not very DWIM-ish, IMHO, but I'm sure that there are good reasons for this confusion, having to do with subtleties of parsing that are beyond me.</p>
<p>Be that as it may, perl needs help with such expressions. In this case the solution is <em>not</em> to prepend a <tt>+</tt>, because that would disambiguate the expression in the direction opposite to what we want. We want perl to regard the <tt>{...}</tt> as a block. The standard trick is to put a bare <tt>;</tt> as the first token after the opening "<tt>{</tt>":
<c>
my @foo = map { ; 1, 2 } 3, 4;
print "@foo\n";
__END__
1 2 1 2
</c>
But if perl had been right originally (meaning that we <em>did</em> want <tt>map</tt>'s first argument to be interpreted as an anonymous hash, and we <em>did</em> have a syntax error (by forgetting the comma after the closing <tt>}</tt>), then we could dispel all possible doubt by adding a leading <tt>+</tt> (and the forgotten comma, of course):
<c>
my @foo = map +{ 1, 2 }, 3, 4;
</c>
As it turns out, in this case adding the missing comma is enough to set perl straight:
<c>
my @foo = map { 1, 2 }, 3, 4;
print "@foo\n";
__END__
HASH(0x814cbb8) HASH(0x814cd5c)
</c>
but according to <tt>[doc://perlref]</tt>, <em>this may change in the future</em>, so I typically put that <tt>+</tt> in there anyway.</p>
<small><p><sup>1</sup> I've used <tt>""</tt> around the <tt>(</tt> to disambiguate a potential smiley. The footnote digit helps too. (: </p></small>
</readmore>
<div class="pmsig"><div class="pmsig-439528">
<p><small>the lowliest monk</small></p>
</div></div>
468605
468605