map {; ... } LIST
https://github.com/rjbs/App-Uni/blob/master/bin/uni#L12
@ARGV = map {; decode('UTF-8', $_) } @ARGV;
上記 map {;
のセミコロンの意味がわからずもやもやしていた。
そんな中、まさにそれの説明が perlfunc.pod に追加された。
http://perl5.git.perl.org/perl.git/commitdiff/24fe90a14d91f512527a158a02ea19d502723856
"{" starts both hash references and blocks, so "map { ..." could be either the start of map BLOCK LIST or map EXPR, LIST. Because Perl doesn't look ahead for the closing "}" it has to take a guess at which it's dealing with based on what it finds just after the "{". Usually it gets it right, but if it doesn't it won't realize something is wrong until it gets to the "}" and encounters the missing (or unexpected) comma. The syntax error will be reported close to the "}", but you'll need to change something near the "{" such as using a unary "+" or semicolon 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 { ("\L$_" => 1) } @array # as does this %hash = map { lc($_) => 1 } @array # and 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 "+{": @hashes = map +{ lc($_) => 1 }, @array # EXPR, so needs # comma at end to get a list of anonymous hashes each with only one entry apiece.
つまり、map {}
の {}
はブロックにも無名ハッシュリファレンスにも解釈可能だから、ブロックだと解釈させたいときはmap {; ... } LIST
などを使うとよい。