File Coverage

blib/lib/Perl/Critic/Policy/Bangs/ProhibitUselessTopic.pm
Criterion Covered Total %
statement 34 36 94.4
branch 10 12 83.3
condition 7 9 77.7
subroutine 9 10 90.0
pod 4 5 80.0
total 64 72 88.8


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Bangs::ProhibitUselessTopic;
2              
3 4     4   1490223 use strict;
  4         12  
  4         366  
4 4     4   23 use warnings;
  4         9  
  4         122  
5 4     4   24 use Readonly;
  4         11  
  4         273  
6              
7 4     4   22 use Perl::Critic::Utils qw{ :severities :classification :ppi };
  4         7  
  4         382  
8 4     4   2568 use base 'Perl::Critic::Policy';
  4         8  
  4         4946  
9              
10             our $VERSION = '1.11_02';
11              
12             Readonly::Scalar my $DESC => q{Useless use of $_};
13             Readonly::Scalar my $EXPL_REGEX => q{$_ may be omitted when matching a regular expression};
14             Readonly::Scalar my $EXPL_FILETEST => q{$_ may be omitted when using a filetest operator};
15              
16 12     12 0 51685 sub supported_parameters { return () }
17 23     23 1 194 sub default_severity { return $SEVERITY_MEDIUM }
18 0     0 1 0 sub default_themes { return qw( bangs complexity ) }
19 9     9 1 119210 sub applies_to { return 'PPI::Token::Magic', 'PPI::Token::Operator' }
20              
21              
22             my @filetest_operators = qw( -r -w -x -o -R -W -X -O -e -z -s -f -d -l -p -S -b -c -u -g -k -T -B -M -A -C );
23             my %filetest_operators = map { ($_ => 1) } @filetest_operators;
24              
25             sub violates {
26 74     74 1 4707 my ( $self, $elem, undef ) = @_;
27              
28 74         195 my $content = $elem->content;
29 74 100       406 if ( $content eq '$_' ) {
30             # Is there an op following the $_ ?
31 25         93 my $op_node = $elem->snext_sibling;
32 25 100 100     667 if ( $op_node && $op_node->isa('PPI::Token::Operator') ) {
33             # If the op is a regex match, then we have an unnecessary $_ .
34 22         64 my $op = $op_node->content;
35 22 100 100     147 if ( $op eq '=~' || $op eq '!~' ) {
36 21         83 return $self->violation( $DESC, $EXPL_REGEX, $elem );
37             }
38             }
39 4         13 return;
40             }
41              
42             # Are we looking at a filetest?
43 49 100       126 if ( $filetest_operators{ $content } ) {
44             # Is there a $_ following it?
45 2         7 my $op_node = $elem->snext_sibling;
46 2 50 33     57 if ( $op_node && $op_node->isa('PPI::Token::Magic') ) {
47 2         7 my $op = $op_node->content;
48 2 50       13 if ( $op eq '$_' ) {
49 2         9 return $self->violation( $DESC, $EXPL_FILETEST, $elem );
50             }
51             }
52 0         0 return;
53             }
54              
55 47         110 return;
56             }
57              
58              
59             1;
60              
61             __END__
62             =head1 NAME
63              
64             Perl::Critic::Policy::Bangs::ProhibitUselessTopic - Explicitly checking a regex against $_ is unnecessary
65              
66             =head1 AFFILIATION
67              
68             This Policy is part of the L<Perl::Critic::Bangs> distribution.
69              
70             =head1 DESCRIPTION
71              
72             Match or substitution operations are performed against variables, such as:
73              
74             $x =~ /foo/;
75             $x =~ s/foo/bar/;
76             $x =~ tr/a-mn-z/n-za-m/;
77              
78             If a variable is not specified, the match is against C<$_>, also known as
79             "the topic".
80              
81             # These are identical.
82             /foo/;
83             $_ =~ /foo/;
84              
85             # These are identical.
86             s/foo/bar/;
87             $_ =~ s/foo/bar/;
88              
89             # These are identical.
90             tr/a-mn-z/n-za-m/;
91             $_ =~ tr/a-mn-z/n-za-m/;
92              
93             Including the C<$_ =~> is unnecessary, adds complexity, and is not
94             idiomatic Perl.
95              
96             Another place that C<$_> is unnecessary is with a filetest operator.
97              
98             # These are identical.
99             my $size = -s $_;
100             my $size = -s;
101              
102             # These are identical.
103             if ( -r $_ ) { ...
104             if ( -r ) { ...
105              
106             =head1 CONFIGURATION
107              
108             This Policy is not configurable except for the standard options.
109              
110             =head1 TO DO
111              
112             I hope to expand this to other places that C<$_> is not needed, like in
113             a call to C<split> or a million other functions where C<$_> is assumed.
114              
115             =head1 AUTHOR
116              
117             Andy Lester <andy@petdance.com>
118              
119             =head1 COPYRIGHT
120              
121             Copyright (c) 2013 Andy Lester <andy@petdance.com>
122              
123             This library is free software; you can redistribute it and/or modify it
124             under the terms of the Artistic License 2.0.
125              
126             =cut