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   5160 use strict;
  7         17  
  7         195  
2 7     7   34 use warnings;
  7         15  
  7         308  
3             package Perl::Critic::Policy::Lax::ProhibitComplexMappings::LinesNotStatements 0.014;
4             # ABSTRACT: prohibit multiline maps, not multistatement maps
5              
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   36 use Perl::Critic::Utils;
  7         14  
  7         129  
31 7     7   5328 use parent qw(Perl::Critic::Policy);
  7         16  
  7         37  
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 16 sub default_severity { $SEVERITY_MEDIUM }
37 0     0 1 0 sub default_themes { qw(lax complexity) }
38 6     6 1 67471 sub applies_to { 'PPI::Token::Word' }
39              
40             sub violates {
41 9     9 1 690 my ($self, $element, undef) = @_;
42              
43 9 100       38 return if $element ne 'map';
44 6 50       158 return if !is_function_call($element);
45              
46 6         1709 my $sib = $element->snext_sibling();
47 6 50       103 return if !$sib;
48              
49 6         14 my $arg = $sib;
50 6 50       26 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       22 return if !$arg;
63 6 100       30 return if !$arg->isa('PPI::Structure::Block');
64              
65             # The moment of truth: does the block contain any newlines?
66 5 100       18 return unless $arg =~ /[\x0d\x0a]/;
67              
68             # more than one child statements
69 1         99 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.014
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 PERL VERSION
111              
112             This library should run on perls released even a long time ago. It should work
113             on any version of perl released in the last five years.
114              
115             Although it may work on older versions of perl, no guarantee is made that the
116             minimum required version will not be increased. The version may be increased
117             for any reason, and there is no promise that patches will be accepted to lower
118             the minimum required perl.
119              
120             =head1 AUTHOR
121              
122             Ricardo Signes <cpan@semiotic.systems>
123              
124             =head1 COPYRIGHT AND LICENSE
125              
126             This software is copyright (c) 2022 by Ricardo Signes <cpan@semiotic.systems>.
127              
128             This is free software; you can redistribute it and/or modify it under
129             the same terms as the Perl 5 programming language system itself.
130              
131             =cut