File Coverage

blib/lib/Perl/Critic/Policy/Lax/ProhibitComplexMappings/LinesNotStatements.pm
Criterion Covered Total %
statement 25 29 86.2
branch 10 16 62.5
condition 0 3 0.0
subroutine 7 8 87.5
pod 4 4 100.0
total 46 60 76.6


line stmt bran cond sub pod time code
1 7     7   3463 use strict;
  7         11  
  7         163  
2 7     7   20 use warnings;
  7         7  
  7         354  
3             package Perl::Critic::Policy::Lax::ProhibitComplexMappings::LinesNotStatements;
4             # ABSTRACT: prohibit multiline maps, not multistatement maps
5             $Perl::Critic::Policy::Lax::ProhibitComplexMappings::LinesNotStatements::VERSION = '0.013';
6             #pod =head1 DESCRIPTION
7             #pod
8             #pod Yes, yes, don't go nuts with map and use it to implement the complex multi-pass
9             #pod fnordsort algorithm. But, come on, people! What's wrong with this:
10             #pod
11             #pod my @localparts = map { my $addr = $_; $addr =~ s/\@.+//; $addr } @addresses;
12             #pod
13             #pod Nothing, that's what!
14             #pod
15             #pod The assumption behind this module is that while the above is okay, the bellow
16             #pod is Right Out:
17             #pod
18             #pod my @localparts = map {
19             #pod my $addr = $_;
20             #pod $addr =~ s/\@.+//;
21             #pod $addr
22             #pod } @addresses;
23             #pod
24             #pod Beyond the fact that it's really ugly, it's just a short step from there to a
25             #pod few included loop structures and then -- oops! -- a return statement.
26             #pod Seriously, people, they're called subroutines. We've had them since Perl 3.
27             #pod
28             #pod =cut
29              
30 7     7   26 use Perl::Critic::Utils;
  7         6  
  7         83  
31 7     7   3440 use parent qw(Perl::Critic::Policy);
  7         8  
  7         28  
32              
33             my $DESCRIPTION = q{The block given to map should fit on one line.};
34             my $EXPLANATION = "If it doesn't fit on one line, turn it into a subroutine.";
35              
36 1     1 1 13 sub default_severity { $SEVERITY_MEDIUM }
37 0     0 1 0 sub default_themes { qw(lax complexity) }
38 6     6 1 36102 sub applies_to { 'PPI::Token::Word' }
39              
40             sub violates {
41 9     9 1 431 my ($self, $element, undef) = @_;
42              
43 9 100       23 return if $element ne 'map';
44 6 50       90 return if !is_function_call($element);
45              
46 6         941 my $sib = $element->snext_sibling();
47 6 50       70 return if !$sib;
48              
49 6         6 my $arg = $sib;
50 6 50       16 if ($arg->isa('PPI::Structure::List')) {
51 0         0 $arg = $arg->schild(0);
52              
53             # Forward looking: PPI might change in v1.200 so schild(0) is a
54             # PPI::Statement::Expression
55 0 0 0     0 if ($arg && $arg->isa('PPI::Statement::Expression')) {
56 0         0 $arg = $arg->schild(0);
57             }
58             }
59              
60             # If it's not a block, it's an expression-style map, which is only one
61             # statement by definition
62 6 50       12 return if !$arg;
63 6 100       17 return if !$arg->isa('PPI::Structure::Block');
64              
65             # The moment of truth: does the block contain any newlines?
66 5 100       12 return unless $arg =~ /[\x0d\x0a]/;
67              
68             # more than one child statements
69 1         65 return $self->violation($DESCRIPTION, $EXPLANATION, $element);
70             }
71              
72             1;
73              
74             __END__
75              
76             =pod
77              
78             =encoding UTF-8
79              
80             =head1 NAME
81              
82             Perl::Critic::Policy::Lax::ProhibitComplexMappings::LinesNotStatements - prohibit multiline maps, not multistatement maps
83              
84             =head1 VERSION
85              
86             version 0.013
87              
88             =head1 DESCRIPTION
89              
90             Yes, yes, don't go nuts with map and use it to implement the complex multi-pass
91             fnordsort algorithm. But, come on, people! What's wrong with this:
92              
93             my @localparts = map { my $addr = $_; $addr =~ s/\@.+//; $addr } @addresses;
94              
95             Nothing, that's what!
96              
97             The assumption behind this module is that while the above is okay, the bellow
98             is Right Out:
99              
100             my @localparts = map {
101             my $addr = $_;
102             $addr =~ s/\@.+//;
103             $addr
104             } @addresses;
105              
106             Beyond the fact that it's really ugly, it's just a short step from there to a
107             few included loop structures and then -- oops! -- a return statement.
108             Seriously, people, they're called subroutines. We've had them since Perl 3.
109              
110             =head1 AUTHOR
111              
112             Ricardo Signes <rjbs@cpan.org>
113              
114             =head1 COPYRIGHT AND LICENSE
115              
116             This software is copyright (c) 2017 by Ricardo Signes <rjbs@cpan.org>.
117              
118             This is free software; you can redistribute it and/or modify it under
119             the same terms as the Perl 5 programming language system itself.
120              
121             =cut