File Coverage

blib/lib/Perl/Critic/Policy/BuiltinFunctions/ProhibitReverseSortBlock.pm
Criterion Covered Total %
statement 23 42 54.7
branch 1 16 6.2
condition 0 6 0.0
subroutine 11 11 100.0
pod 4 5 80.0
total 39 80 48.7


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::BuiltinFunctions::ProhibitReverseSortBlock;
2              
3 40     40   25994 use 5.010001;
  40         199  
4 40     40   297 use strict;
  40         133  
  40         992  
5 40     40   273 use warnings;
  40         157  
  40         997  
6 40     40   273 use Readonly;
  40         159  
  40         2176  
7              
8 40     40   326 use Perl::Critic::Utils qw{ :severities :classification };
  40         150  
  40         2191  
9 40     40   14143 use parent 'Perl::Critic::Policy';
  40         145  
  40         264  
10              
11             our $VERSION = '1.150';
12              
13             #-----------------------------------------------------------------------------
14              
15             Readonly::Scalar my $DESC => q{Forbid $b before $a in sort blocks}; ## no critic (InterpolationOfMetachars)
16             Readonly::Scalar my $EXPL => [ 152 ];
17              
18             #-----------------------------------------------------------------------------
19              
20 89     89 0 1679 sub supported_parameters { return () }
21 74     74 1 342 sub default_severity { return $SEVERITY_LOWEST }
22 84     84 1 362 sub default_themes { return qw(core pbp cosmetic) }
23 30     30 1 94 sub applies_to { return 'PPI::Token::Word' }
24              
25             #-----------------------------------------------------------------------------
26              
27             sub violates {
28 329     329 1 563 my ($self, $elem, $doc) = @_;
29              
30 329 50       538 return if $elem->content() ne 'sort';
31 0 0         return if ! is_function_call($elem);
32              
33 0           my $sib = $elem->snext_sibling();
34 0 0         return if !$sib;
35              
36 0           my $arg = $sib;
37 0 0         if ( $arg->isa('PPI::Structure::List') ) {
38 0           $arg = $arg->schild(0);
39             # Forward looking: PPI might change in v1.200 so schild(0) is a PPI::Statement::Expression
40 0 0 0       if ( $arg && $arg->isa('PPI::Statement::Expression') ) {
41 0           $arg = $arg->schild(0);
42             }
43             }
44 0 0 0       return if !$arg || !$arg->isa('PPI::Structure::Block');
45              
46             # If we get here, we found a sort with a block as the first arg
47              
48             # Look at each statement in the block separately.
49             # $a is +1, $b is -1, sum should always be >= 0.
50             # This may go badly if there are conditionals or loops or other
51             # sub-statements...
52 0           for my $statement ($arg->children) {
53 0           my @sort_vars = $statement =~ m/\$([ab])\b/gxms;
54 0           my $count = 0;
55 0           for my $sort_var (@sort_vars) {
56 0 0         if ($sort_var eq 'a') {
57 0           $count++;
58             } else {
59 0           $count--;
60 0 0         if ($count < 0) {
61             # Found too many C<$b>s too early
62 0           return $self->violation( $DESC, $EXPL, $elem );
63             }
64             }
65             }
66             }
67 0           return; #ok
68             }
69              
70             1;
71              
72             #-----------------------------------------------------------------------------
73              
74             __END__
75              
76             =pod
77              
78             =head1 NAME
79              
80             Perl::Critic::Policy::BuiltinFunctions::ProhibitReverseSortBlock - Forbid $b before $a in sort blocks.
81              
82              
83             =head1 AFFILIATION
84              
85             This Policy is part of the core L<Perl::Critic|Perl::Critic>
86             distribution.
87              
88              
89             =head1 DESCRIPTION
90              
91             Conway says that it is much clearer to use C<reverse> than to flip
92             C<$a> and C<$b> around in a C<sort> block. He also suggests that, in
93             newer perls, C<reverse> is specifically looked for and optimized, and
94             in the case of a simple reversed string C<sort>, using C<reverse> with
95             a C<sort> with no block is faster even in old perls.
96              
97             my @foo = sort { $b cmp $a } @bar; #not ok
98             my @foo = reverse sort @bar; #ok
99              
100             my @foo = sort { $b <=> $a } @bar; #not ok
101             my @foo = reverse sort { $a <=> $b } @bar; #ok
102              
103              
104             =head1 CONFIGURATION
105              
106             This Policy is not configurable except for the standard options.
107              
108              
109             =head1 AUTHOR
110              
111             Chris Dolan <cdolan@cpan.org>
112              
113              
114             =head1 COPYRIGHT
115              
116             Copyright (c) 2006-2011 Chris Dolan.
117              
118             This program is free software; you can redistribute it and/or modify
119             it under the same terms as Perl itself.
120              
121             =cut
122              
123             # Local Variables:
124             # mode: cperl
125             # cperl-indent-level: 4
126             # fill-column: 78
127             # indent-tabs-mode: nil
128             # c-indentation-style: bsd
129             # End:
130             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :