When I entered our rooms in Paris after a day on the boulevards, I found C. Auguste Dupin at his desk contemplating a scrap of paper. "A problem?" I asked.

"A death. And a rather gruesome one, n'est-ce pas?" he replied, handing me the paper. On it I saw:



$ perl -e '%h = map { "-$_" => 1 } qw{ foo bar };'

Not enough arguments for map at -e line 1, near "} qw{ foo bar }"

syntax error at -e line 1, near "} qw{ foo bar }"

Execution of -e aborted due to compilation errors.



Well, a map takes either a block or an expression followed by a comma, and either must be followed by a list. The block was there, and so was the list. Clearly a neophite had been playing with bleadperl, and paid the price. With a rueful shake of my head, I silently passed the paper back to the detective.

"No, this was a production release of Perl, mon ami."

"But how --" I expostulated.

"-- did I know what you were thinking? Simple observation. When I gave you the paper, your brow contracted in puzzlement. This was succeeded by the abstracted expression of deep thought. Your right thumb played back and forth between the first two fingers, as though considering two alternatives, thus I knew you were thinking of the two forms of map . Your expression of rueful pity for the victim as you returned the paper to me completed the picture."

"But how --" I began again.

"-- can a production version of Perl fail to parse such an obviously correct map ? Ah, that is a deeper problem. The solution lies in the fact that in Perl, curly brackets are overloaded, and may be used either as block delimiters or a hash constructor.

"The map takes either an expression or a block as its first argument, and the documentation states plainly that the Perl parser must choose between these alternatives before it analyzes the entire statement, and that, absent clear clues, it guesses." His face assumed an expression of something like revulsion as he pronounced the last word. "Since the parse failure makes no sense with a block, it must be that Perl parsed the curly brackets as a hash constructor, and therefore as an expression. The comma which must follow an expression was not found, lacking which a painful death ensued.

"But how --" I broke in for the third time.

"-- could this tragedy have been prevented? Nothing simpler. The perlref document states that a unary plus sign before the left curly bracket forces it to be interpreted as a hash constructor, and a semicolon after it forces the interpretation to be a block. Two simple strokes could have prevented this horrible death."

And with his pen, he inserted the semicolon which would have spared the victim's life:



$ perl -e '%h = map {; "-$_" => 1 } qw{ foo bar };'

