File Coverage

blib/lib/Perl/Critic/Policy/ValuesAndExpressions/ProhibitInterpolationOfLiterals.pm
Criterion Covered Total %
statement 44 44 100.0
branch 13 14 92.8
condition n/a
subroutine 15 15 100.0
pod 4 5 80.0
total 76 78 97.4


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::ValuesAndExpressions::ProhibitInterpolationOfLiterals;
2              
3 40     40   28519 use 5.010001;
  40         164  
4 40     40   245 use strict;
  40         104  
  40         815  
5 40     40   196 use warnings;
  40         110  
  40         970  
6 40     40   234 use Readonly;
  40         100  
  40         2484  
7              
8 40     40   316 use List::SomeUtils qw(any);
  40         118  
  40         2260  
9              
10 40     40   272 use Perl::Critic::Utils qw{ :characters :severities :data_conversion };
  40         112  
  40         2283  
11 40     40   13630 use parent 'Perl::Critic::Policy';
  40         114  
  40         245  
12              
13             our $VERSION = '1.146';
14              
15             #-----------------------------------------------------------------------------
16              
17             Readonly::Scalar my $DESC => q{Useless interpolation of literal string};
18             Readonly::Scalar my $EXPL => [51];
19              
20             #-----------------------------------------------------------------------------
21              
22             sub supported_parameters {
23             return (
24             {
25 101     101 0 2432 name => 'allow',
26             description =>
27             'Kinds of delimiters to permit, e.g. "qq{", "qq(", "qq[", "qq/".',
28             default_string => $EMPTY,
29             parser => \&_parse_allow,
30             },
31             {
32             name => 'allow_if_string_contains_single_quote',
33             description =>
34             q<If the string contains ' characters, allow "" to quote it.>,
35             default_string => '0',
36             behavior => 'boolean',
37             },
38             );
39             }
40              
41 93     93 1 471 sub default_severity { return $SEVERITY_LOWEST }
42 84     84 1 370 sub default_themes { return qw( core pbp cosmetic ) }
43 40     40 1 165 sub applies_to { return qw(PPI::Token::Quote::Double
44             PPI::Token::Quote::Interpolate) }
45              
46             #-----------------------------------------------------------------------------
47              
48             Readonly::Scalar my $MAX_SPECIFICATION_LENGTH => 3;
49              
50             sub _parse_allow {
51 99     99   534 my ($self, $parameter, $config_string) = @_;
52              
53 99         290 my @allow;
54              
55 99 100       523 if (defined $config_string) {
56 6         31 @allow = words_from_string( $config_string );
57             #Try to be forgiving with the configuration...
58 6         37 for (@allow) {
59 10 100       54 m{ \A qq }xms || ($_ = 'qq' . $_)
60             } #Add 'qq'
61 6         25 for (@allow) {
62 10 100       45 (length $_ <= $MAX_SPECIFICATION_LENGTH) || chop
63             } #Chop closing char
64             }
65              
66 99         448 $self->{_allow} = \@allow;
67              
68 99         359 return;
69             }
70              
71             #-----------------------------------------------------------------------------
72              
73             sub violates {
74 39     39 1 131 my ( $self, $elem, undef ) = @_;
75              
76             # Skip if this string needs interpolation
77 39 100       130 return if _has_interpolation($elem);
78              
79             # Overlook allowed quote styles
80 31 100   31   582 return if any { $elem =~ m{ \A \Q$_\E }xms } @{ $self->{_allow} };
  31         352  
  31         158  
81              
82             # If the flag is set, allow "I'm here".
83 21 100       169 if ( $self->{_allow_if_string_contains_single_quote} ) {
84 2 50       7 return if index ($elem, $QUOTE) >= 0;
85             }
86              
87             # Must be a violation
88 19         139 return $self->violation( $DESC, $EXPL, $elem );
89             }
90              
91             #-----------------------------------------------------------------------------
92              
93             sub _has_interpolation {
94 39     39   77 my $elem = shift;
95 39         116 return $elem =~ m<
96             (?: \A | [^\\] )
97             (?: \\{2} )*
98             (?: [\$\@] \S+ | \\[tnrfbae0xcNLuLUEQ] )
99             >xmso;
100             }
101              
102             1;
103              
104             __END__
105              
106             #-----------------------------------------------------------------------------
107              
108             =pod
109              
110             =head1 NAME
111              
112             Perl::Critic::Policy::ValuesAndExpressions::ProhibitInterpolationOfLiterals - Always use single quotes for literal strings.
113              
114              
115             =head1 AFFILIATION
116              
117             This Policy is part of the core L<Perl::Critic|Perl::Critic>
118             distribution.
119              
120              
121             =head1 DESCRIPTION
122              
123             Don't use double-quotes or C<qq//> if your string doesn't require
124             interpolation. This saves the interpreter a bit of work and it lets
125             the reader know that you really did intend the string to be literal.
126              
127             print "foobar"; #not ok
128             print 'foobar'; #ok
129             print qq/foobar/; #not ok
130             print q/foobar/; #ok
131              
132             print "$foobar"; #ok
133             print "foobar\n"; #ok
134             print qq/$foobar/; #ok
135             print qq/foobar\n/; #ok
136              
137             print qq{$foobar}; #preferred
138             print qq{foobar\n}; #preferred
139              
140             Use of double-quotes might be reasonable if the string contains single
141             quote (') characters:
142              
143             print "it's me"; # ok, if configuration flag set
144              
145              
146             =head1 CONFIGURATION
147              
148             The types of quoting styles to exempt from this policy can be
149             configured via the C<allow> option. This must be a
150             whitespace-delimited combination of some or all of the following
151             styles: C<qq{}>, C<qq()>, C<qq[]>, and C<qq//>.
152              
153             This is useful because some folks have configured their editor to
154             apply special syntax highlighting within certain styles of quotes.
155             For example, you can tweak C<vim> to use SQL highlighting for
156             everything that appears within C<qq{}> or C<qq[]> quotes. But if
157             those strings are literal, Perl::Critic will complain. To prevent
158             this, put the following in your F<.perlcriticrc> file:
159              
160             [ValuesAndExpressions::ProhibitInterpolationOfLiterals]
161             allow = qq{} qq[]
162              
163             The flag C<allow_if_string_contains_single_quote> permits
164             double-quoted strings if the string contains a single quote (')
165             character. It defaults to off; to turn it on put the following in
166             your F<.perlcriticrc> file:
167              
168             [ValuesAndExpressions::ProhibitInterpolationOfLiterals]
169             allow_if_string_contains_single_quote = 1
170              
171              
172             =head1 SEE ALSO
173              
174             L<Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars|Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars>
175              
176             =head1 AUTHOR
177              
178             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
179              
180             =head1 COPYRIGHT
181              
182             Copyright (c) 2005-2021 Imaginative Software Systems. All rights reserved.
183              
184             This program is free software; you can redistribute it and/or modify
185             it under the same terms as Perl itself. The full text of this license
186             can be found in the LICENSE file included with this module.
187              
188             =cut
189              
190             # Local Variables:
191             # mode: cperl
192             # cperl-indent-level: 4
193             # fill-column: 78
194             # indent-tabs-mode: nil
195             # c-indentation-style: bsd
196             # End:
197             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :