File: ProhibitInterpolationOfLiterals.pm

package info (click to toggle)
libperl-critic-perl 1.156-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,544 kB
  • sloc: perl: 24,092; lisp: 341; makefile: 7
file content (197 lines) | stat: -rw-r--r-- 5,684 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
package Perl::Critic::Policy::ValuesAndExpressions::ProhibitInterpolationOfLiterals;

use 5.010001;
use strict;
use warnings;
use Readonly;

use List::SomeUtils qw(any);

use Perl::Critic::Utils qw{ :characters :severities :data_conversion };
use parent 'Perl::Critic::Policy';

our $VERSION = '1.156';

#-----------------------------------------------------------------------------

Readonly::Scalar my $DESC => q{Useless interpolation of literal string};
Readonly::Scalar my $EXPL => [51];

#-----------------------------------------------------------------------------

sub supported_parameters {
    return (
        {
            name               => 'allow',
            description        =>
                'Kinds of delimiters to permit, e.g. "qq{", "qq(", "qq[", "qq/".',
            default_string     => $EMPTY,
            parser             => \&_parse_allow,
        },
        {
            name               => 'allow_if_string_contains_single_quote',
            description        =>
                q<If the string contains ' characters, allow "" to quote it.>,
            default_string     => '0',
            behavior           => 'boolean',
        },
    );
}

sub default_severity { return $SEVERITY_LOWEST        }
sub default_themes   { return qw( core pbp cosmetic ) }
sub applies_to       { return qw(PPI::Token::Quote::Double
                                 PPI::Token::Quote::Interpolate) }

#-----------------------------------------------------------------------------

Readonly::Scalar my $MAX_SPECIFICATION_LENGTH => 3;

sub _parse_allow {
    my ($self, undef, $config_string) = @_;

    my @allow;

    if (defined $config_string) {
        @allow = words_from_string( $config_string );
        #Try to be forgiving with the configuration...
        for (@allow) {
            m{ \A qq }xms || ($_ = 'qq' . $_)
        }  #Add 'qq'
        for (@allow) {
            (length $_ <= $MAX_SPECIFICATION_LENGTH) || chop
        }    #Chop closing char
    }

    $self->{_allow} = \@allow;

    return;
}

#-----------------------------------------------------------------------------

sub violates {
    my ( $self, $elem, undef ) = @_;

    # Skip if this string needs interpolation
    return if _has_interpolation($elem);

    # Overlook allowed quote styles
    return if any { $elem =~ m{ \A \Q$_\E }xms } @{ $self->{_allow} };

    # If the flag is set, allow "I'm here".
    if ( $self->{_allow_if_string_contains_single_quote} ) {
        return if index ($elem, $QUOTE) >= 0;
    }

    # Must be a violation
    return $self->violation( $DESC, $EXPL, $elem );
}

#-----------------------------------------------------------------------------

sub _has_interpolation {
    my $elem = shift;
    return $elem =~ m<
        (?: \A | [^\\] )
        (?: \\{2} )*
        (?: [\$\@] \S+ | \\[tnrfbae0xcNLuLUEQ] )
    >xmso;
}

1;

__END__

#-----------------------------------------------------------------------------

=pod

=head1 NAME

Perl::Critic::Policy::ValuesAndExpressions::ProhibitInterpolationOfLiterals - Always use single quotes for literal strings.


=head1 AFFILIATION

This Policy is part of the core L<Perl::Critic|Perl::Critic>
distribution.


=head1 DESCRIPTION

Don't use double-quotes or C<qq//> if your string doesn't require
interpolation.  This saves the interpreter a bit of work and it lets
the reader know that you really did intend the string to be literal.

    print "foobar";     #not ok
    print 'foobar';     #ok
    print qq/foobar/;   #not ok
    print q/foobar/;    #ok

    print "$foobar";    #ok
    print "foobar\n";   #ok
    print qq/$foobar/;  #ok
    print qq/foobar\n/; #ok

    print qq{$foobar};  #preferred
    print qq{foobar\n}; #preferred

Use of double-quotes might be reasonable if the string contains single
quote (') characters:

    print "it's me";    # ok, if configuration flag set


=head1 CONFIGURATION

The types of quoting styles to exempt from this policy can be
configured via the C<allow> option.  This must be a
whitespace-delimited combination of some or all of the following
styles: C<qq{}>, C<qq()>, C<qq[]>, and C<qq//>.

This is useful because some folks have configured their editor to
apply special syntax highlighting within certain styles of quotes.
For example, you can tweak C<vim> to use SQL highlighting for
everything that appears within C<qq{}> or C<qq[]> quotes.  But if
those strings are literal, Perl::Critic will complain.  To prevent
this, put the following in your F<.perlcriticrc> file:

    [ValuesAndExpressions::ProhibitInterpolationOfLiterals]
    allow = qq{} qq[]

The flag C<allow_if_string_contains_single_quote> permits
double-quoted strings if the string contains a single quote (')
character.  It defaults to off; to turn it on put the following in
your F<.perlcriticrc> file:

    [ValuesAndExpressions::ProhibitInterpolationOfLiterals]
    allow_if_string_contains_single_quote = 1


=head1 SEE ALSO

L<Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars|Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars>

=head1 AUTHOR

Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>

=head1 COPYRIGHT

Copyright (c) 2005-2021 Imaginative Software Systems.  All rights reserved.

This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.  The full text of this license
can be found in the LICENSE file included with this module.

=cut

# Local Variables:
#   mode: cperl
#   cperl-indent-level: 4
#   fill-column: 78
#   indent-tabs-mode: nil
#   c-indentation-style: bsd
# End:
# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :