1 ##############################################################################
2 # $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/Perl-Critic/lib/Perl/Critic/Policy/ValuesAndExpressions/ProhibitQuotesAsQuotelikeOperatorDelimiters.pm $
3 # $Date: 2008-07-03 10:19:10 -0500 (Thu, 03 Jul 2008) $
6 ##############################################################################
8 package Perl::Critic::Policy::ValuesAndExpressions::ProhibitQuotesAsQuotelikeOperatorDelimiters;
15 use Perl::Critic::Utils qw{
16 :booleans :characters :severities :data_conversion
18 use base 'Perl::Critic::Policy';
20 our $VERSION = '1.088';
22 #-----------------------------------------------------------------------------
24 Readonly::Hash my %DESCRIPTIONS => (
25 $QUOTE => q{Single-quote used as quote-like operator delimiter},
26 $DQUOTE => q{Double-quote used as quote-like operator delimiter},
27 $BACKTICK => q{Back-quote (back-tick) used as quote-like operator delimiter},
30 Readonly::Scalar my $EXPL =>
31 q{Using quotes as delimiters for quote-like operators obfuscates code};
33 Readonly::Array my @OPERATORS => qw{ m q qq qr qw qx s tr y };
35 Readonly::Hash my %INFO_RETRIEVERS_BY_PPI_CLASS => (
36 'PPI::Token::Quote::Literal' => \&_info_for_single_character_operator,
37 'PPI::Token::Quote::Interpolate' => \&_info_for_two_character_operator,
38 'PPI::Token::QuoteLike::Command' => \&_info_for_two_character_operator,
39 'PPI::Token::QuoteLike::Regexp' => \&_info_for_two_character_operator,
40 'PPI::Token::QuoteLike::Words' => \&_info_for_two_character_operator,
41 'PPI::Token::Regexp::Match' => \&_info_for_match,
42 'PPI::Token::Regexp::Substitute' => \&_info_for_single_character_operator,
43 'PPI::Token::Regexp::Transliterate' => \&_info_for_transliterate,
46 #-----------------------------------------------------------------------------
48 sub supported_parameters {
51 name => 'single_quote_allowed_operators',
53 'The operators to allow single-quotes as delimiters for.',
54 default_string => 'm s qr qx',
55 behavior => 'enumeration',
56 enumeration_values => [ @OPERATORS ],
57 enumeration_allow_multiple_values => 1,
60 name => 'double_quote_allowed_operators',
62 'The operators to allow double-quotes as delimiters for.',
63 default_string => $EMPTY,
64 behavior => 'enumeration',
65 enumeration_values => [ @OPERATORS ],
66 enumeration_allow_multiple_values => 1,
69 name => 'back_quote_allowed_operators',
71 'The operators to allow back-quotes (back-ticks) as delimiters for.',
72 default_string => $EMPTY,
73 behavior => 'enumeration',
74 enumeration_values => [ @OPERATORS ],
75 enumeration_allow_multiple_values => 1,
80 sub default_severity { return $SEVERITY_MEDIUM }
81 sub default_themes { return qw( core maintenance ) }
85 PPI::Token::Quote::Interpolate
86 PPI::Token::Quote::Literal
87 PPI::Token::QuoteLike::Command
88 PPI::Token::QuoteLike::Regexp
89 PPI::Token::QuoteLike::Words
90 PPI::Token::Regexp::Match
91 PPI::Token::Regexp::Substitute
92 PPI::Token::Regexp::Transliterate
96 #-----------------------------------------------------------------------------
98 sub initialize_if_enabled {
99 my ($self, $config) = @_;
101 $self->{_allowed_operators_by_delimiter} = {
102 $QUOTE => $self->_single_quote_allowed_operators(),
103 $DQUOTE => $self->_double_quote_allowed_operators(),
104 $BACKTICK => $self->_back_quote_allowed_operators(),
110 #-----------------------------------------------------------------------------
112 sub _single_quote_allowed_operators {
115 return $self->{_single_quote_allowed_operators};
118 sub _double_quote_allowed_operators {
121 return $self->{_double_quote_allowed_operators};
124 sub _back_quote_allowed_operators {
127 return $self->{_back_quote_allowed_operators};
130 sub _allowed_operators_by_delimiter {
133 return $self->{_allowed_operators_by_delimiter};
136 #-----------------------------------------------------------------------------
139 my ( $self, $elem, undef ) = @_;
141 my $info_retriever = $INFO_RETRIEVERS_BY_PPI_CLASS{ ref $elem };
142 return if not $info_retriever;
144 my ($operator, $delimiter) = $info_retriever->( $elem );
146 my $allowed_operators =
147 $self->_allowed_operators_by_delimiter()->{$delimiter};
148 return if not $allowed_operators;
150 if ( not $allowed_operators->{$operator} ) {
151 return $self->violation( $DESCRIPTIONS{$delimiter}, $EXPL, $elem );
157 #-----------------------------------------------------------------------------
159 sub _info_for_single_character_operator {
162 ## no critic (ProhibitParensWithBuiltins)
163 return ( substr ($elem, 0, 1), substr ($elem, 1, 1) );
167 #-----------------------------------------------------------------------------
169 sub _info_for_two_character_operator {
172 ## no critic (ProhibitParensWithBuiltins)
173 return ( substr ($elem, 0, 2), substr ($elem, 2, 1) );
177 #-----------------------------------------------------------------------------
179 sub _info_for_match {
182 if ( $elem =~ m/ ^ m /xms ) {
183 return ('m', substr $elem, 1, 1);
189 #-----------------------------------------------------------------------------
191 sub _info_for_transliterate {
194 if ( $elem =~ m/ ^ tr /xms ) {
195 return ('tr', substr $elem, 2, 1);
198 return ('y', substr $elem, 1, 1);
206 #-----------------------------------------------------------------------------
210 =for stopwords MSCHWERN
214 Perl::Critic::Policy::ValuesAndExpressions::ProhibitQuotesAsQuotelikeOperatorDelimiters - Don't use quotes (C<'>, C<">, C<`>) as delimiters for the quote-like operators.
219 This Policy is part of the core L<Perl::Critic> distribution.
224 With the obvious exception of using single-quotes to prevent
225 interpolation, using quotes with the quote-like operators kind of
226 defeats the purpose of them and produces obfuscated code, causing
227 problems for future maintainers and their editors/IDEs.
237 $x = qx`date`; #not ok
240 $x =~ s"s"x"; #not ok
241 $x =~ tr"t"r"; #not ok
242 $x =~ y"x"y"; #not ok
247 $x = qx'finger foo@bar'; #ok
252 This policy has three options: C<single_quote_allowed_operators>,
253 C<double_quote_allowed_operators>, and
254 C<back_quote_allowed_operators>, which control which operators are
255 allowed to use each of C<'>, C<">, C<`> as delimiters, respectively.
257 The values allowed for these options are a whitespace delimited
258 selection of the C<m>, C<q>, C<qq>, C<qr>, C<qw>, C<qx>, C<s>, C<tr>,
261 By default, double quotes and back quotes (backticks) are not allowed
262 as delimiters for any operators and single quotes are allowed as
263 delimiters for the C<m>, C<qr>, C<qx>, and C<s> operators. These
264 defaults are equivalent to having the following in your
267 [ValuesAndExpressions::ProhibitQuotesAsQuotelikeOperatorDelimiters]
268 single_quote_allowed_operators = m s qr qx
269 double_quote_allowed_operators =
270 back_quote_allowed_operators =
280 Elliot Shank C<< <perl@galumph.com> >>
285 Copyright (c) 2007-2008 Elliot Shank. All rights reserved.
287 This program is free software; you can redistribute it and/or modify
288 it under the same terms as Perl itself. The full text of this license
289 can be found in the LICENSE file included with this module.
295 # cperl-indent-level: 4
297 # indent-tabs-mode: nil
298 # c-indentation-style: bsd
300 # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :