Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Perl-Critic CPAN distribution.

Report information
The Basics
Id: 67499
Status: open
Priority: 0/
Queue: Perl-Critic

People
Owner: Nobody in particular
Requestors: cjay.martin [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Unimportant
Broken in: 1.115
Fixed in: (no value)



Subject: "Complex Matching" and "Comma used to separate statements" catches a one-liner
Perl::Critic::Policy::BuiltinFunctions::ProhibitComplexMappings and Perl::Critic::Policy::ValuesAndExpressions::ProhibitCommaSeparatedStatem ents Perlcritic caught a one-line map with both these errors. Here's the minimal code that flags both errors: my @in = ( { foo => 1 }, { bar => 2 }, { baz => 3 } ); my @out = map { { %$_ }, } @in; ...gave me the warnings: perlcritic --stern ~/test.pl Map blocks should have a single statement at line 5, column 11. See page 113 of PBP. (Severity: 3) Comma used to separate statements at line 5, column 24. See pages 68,71 of PBP. (Severity: 4) Info: Perl Version: 5.10.1 OS: Ubuntu 10.4 I don't know perlcritic well enough myself to patch this, but if nobody touches it when I finally have the time to learn it, I might look into it.
On Fri Apr 15 16:44:52 2011, cjay.martin@gmail.com wrote: Show quoted text
> Perl::Critic::Policy::BuiltinFunctions::ProhibitComplexMappings > and > Perl::Critic::Policy::ValuesAndExpressions::ProhibitCommaSeparatedStatem > ents > > Perlcritic caught a one-line map with both these errors. > > > Here's the minimal code that flags both errors: > > my @in = ( { foo => 1 }, { bar => 2 }, { baz => 3 } ); > my @out = map { { %$_ }, } @in; > > ...gave me the warnings: > > perlcritic --stern ~/test.pl > Map blocks should have a single statement at line 5, column 11. See > page 113 of PBP. (Severity: 3) > Comma used to separate statements at line 5, column 24. See pages 68,71 > of PBP. (Severity: 4) > > > > > Info: > > Perl Version: 5.10.1 > OS: Ubuntu 10.4 > > > I don't know perlcritic well enough myself to patch this, but if nobody > touches it when I finally have the time to learn it, I might look into > it.
This is really two issues. The ValuesAndExpressions::ProhibitCommaSeparatedStatements notice looks to me like a true positive. The curly brackets after the map are a block, and the comma appears at the top level in the block, therefore it is a statement separator. The BuiltinFunctions::ProhibitComplexMappings is a false positive, and yours is not the first ticket in the queue for this. Perl::Critic relies on PPI to parse Perl. There are a number of cases, including yours, where PPI calls a set of curly brackets a block, where Perl sees them as a hash reference constructor. The problem is that Perl uses undocumented heuristics to disambiguate between blocks and hash constructors, and nobody (so far) has been brave enough to sort this particular problem out, for fear of breaking something else. If you are looking for a way to suppress the warning which is terser than '## no critic (ProhibitComplexMappings), you can put a unary plus before the inner left curly bracket. This is Perl's official way to force curly brackets to be interpreted as a hash reference constructor (see perlref), like this: my @out = map { +{ %$ } } @in; Yes, it looks funny, but that is the way B::Deparse renders your statement: $ perl -MO=Deparse -e 'my @out = map { { %$_ }, } @in;' my(@out) = map({+{%$_};} @in); -e syntax OK