NAME
Perl::Critic::Policy::ValuesAndExpressions::UseConsistentQuoting - Use consistent and optimal quoting
VERSION
version v0.1.0
SYNOPSIS
# Bad examples:
my $greeting = 'hello'; # use double quotes for simple strings
my @words = qw{word(with)parens}; # use qw[] for unbalanced content
my $text = qq(simple); # use "" instead of qq()
my $file = q!path/to/file!; # use "" instead of q()
# Good examples:
my $greeting = "hello"; # double quotes for simple strings
my @words = qw[ word(with)parens ]; # optimal delimiter choice
my $text = "simple"; # "" preferred over qq()
my $file = "path/to/file"; # "" reduces punctuation
DESCRIPTION
This policy enforces consistent quoting to improve code readability and maintainability. It applies three simple rules:
Rule 1: Reduce punctuation
Prefer fewer characters and simpler syntax. Prefer real quotes over quote-like operators when possible.
# Good
my $text = "hello world"; # "" preferred over qq()
my $literal = 'contains$literal'; # '' preferred over q()
my $path = "path/to/file"; # simple quotes reduce punctuation
# Bad
my $text = qq(hello world); # unnecessary quote operator
my $literal = q(contains$literal); # unnecessary quote operator
my $path = q!path/to/file!; # unnecessary quote operator
Rule 2: Prefer interpolated strings
If it doesn't matter whether a string is interpolated or not, prefer the interpolated version (double quotes).
# Good
my $name = "John"; # simple string uses double quotes
my $email = 'user@domain.com'; # literal @ uses single quotes
my $var = 'Price: $10'; # literal $ uses single quotes
# Bad
my $name = 'John'; # should use double quotes
Rule 3: Use bracket delimiters in preference order
If the best choice is a quote-like operator, prefer ()
, []
, <>
, or {}
in that order.
# Good
my @words = qw( simple list ); # () preferred when content is simple
my @data = qw[ has(parens) ]; # [] optimal - handles unbalanced ()
my $cmd = qx( has[brackets] ); # () optimal - handles unbalanced []
my $text = q( has<angles> ); # () optimal - handles unbalanced <>
# Bad - exotic delimiters
my @words = qw/word word/; # should use qw()
my $path = q|some|path|; # should use ""
my $text = qq#some#text#; # should use ""
Special Case: Use statements
Use statements have special quoting requirements for their import lists:
Modules with no arguments or empty parentheses are acceptable
Modules with one argument may use double quotes
""
orqw( )
Modules with multiple arguments must use
qw( )
with parentheses only
This allows for compatibility with perlimports.
# Good
use Foo; # no arguments
use Bar (); # empty parentheses
use Baz "single_arg"; # one argument with double quotes
use Qux qw( single_arg ); # one argument with qw()
use Quux qw( arg1 arg2 arg3 ); # multiple arguments with qw()
# Bad
use Foo 'single_arg'; # single quotes not allowed
use Bar "arg1", "arg2"; # multiple arguments need qw()
use Baz qw[ arg1 arg2 ]; # qw() must use parentheses only
use Qux qw{ arg1 arg2 }; # qw() must use parentheses only
Special Case: Newlines
Strings containing newlines do not follow the rules. But note that outside of a few very special cases, strings with literal newlines are not a good idea.
# Allowed
my $text = qq(
line 1
line 2
);
RATIONALE
Minimising escape characters improves readability and reduces errors
Simple quotes are preferred over their
q()
andqq()
equivalents when possibleDouble quotes are preferred for consistency and to allow potential interpolation
Many years ago, Tom Christiansen wrote a lengthy article on how perl's default quoting system is interpolation, and not interpolating means something extraordinary is happening. I can't find the original article, but you can see that double quotes are used by default in The Perl Cookbook, for example.
Only bracket delimiters should be used (no exotic delimiters like
/
,|
,#
, etc.)Optimal delimiter selection reduces visual noise in code
AFFILIATION
This Policy is part of the Perl::Critic::PJCJ distribution.
CONFIGURATION
This Policy is not configurable except for the standard options.
EXAMPLES
String Literals
# Bad
my $greeting = 'hello'; # Rule 2: should use double quotes
my $email = "user@domain.com"; # Rule 2: should use single quotes
# (literal @)
my $path = 'C:\Program Files'; # Rule 2: should use double quotes
# Good
my $greeting = "hello"; # double quotes for simple strings
my $email = 'user@domain.com'; # single quotes for literal @
my $path = "C:\\Program Files"; # double quotes handle backslashes
Quote Operators
# Bad
my $simple = q(hello); # Rule 1: should use ''
my $text = qq(hello); # Rule 1: should use ""
my @words = qw/one two/; # Rule 3: should use qw( )
my $cmd = qx|ls|; # Rule 3: should use qx( )
# Good
my $simple = 'hello$literal'; # single quotes for literal content
my $text = "hello"; # double quotes preferred
my @words = qw( one two ); # bracket delimiters only
my $cmd = qx( ls ); # bracket delimiters only
Optimal Delimiter Selection
# Bad - unbalanced delimiters
my @list = qw(word(with)parens); # Rules 1, 3: unbalanced () in content
my $cmd = qx[command[with]brackets]; # Rules 1, 3: unbalanced [] in content
my $text = q{word{with}braces}; # Rules 1, 3: unbalanced {} in content
# Good - balanced delimiters
my @list = qw[ word(with)parens ]; # [] handles parentheses in content
my $cmd = qx( command[with]brackets ); # () handles brackets in content
Complex Content
# When content has multiple quote types, quote-like operators may be needed
my $both = qq(has 'single' and "double" quotes); # qq() handles both
# quote types cleanly
Use Statement Examples
# Bad
use Foo 'single_arg'; # single quotes not allowed
use Bar "arg1", "arg2"; # multiple args need qw()
use Baz qw[ arg1 arg2 ]; # qw() must use parentheses
use Qux qw{ arg1 arg2 arg3 }; # qw() must use parentheses
# Good
use Foo; # no arguments allowed
use Bar (); # empty parentheses allowed
use Baz "single_arg"; # one argument with double quotes
use Qux qw( single_arg ); # one argument with qw()
use Quux qw( arg1 arg2 arg3 ); # multiple arguments with qw() only
METHODS
supported_parameters
This policy has no configurable parameters.
violates
The main entry point for policy violation checking. Uses a dispatch table to route different quote token types to their appropriate checking methods. This design allows for efficient handling of the six different PPI token types that represent quoted strings and quote-like operators.
would_interpolate
Determines whether a string would perform variable interpolation if placed in double quotes. This is critical for deciding between single and double quotes - strings that would interpolate variables should use single quotes to preserve literal content, while non-interpolating strings should use double quotes for consistency.
Uses PPI's authoritative parsing to detect interpolation rather than regex patterns, ensuring accurate detection of complex cases like literal variables.
delimiter_preference_order
Establishes the preference hierarchy for bracket delimiters when multiple options handle the content equally well. The policy prefers delimiters in this order: ()
> []
> <>
> {}
.
This ordering balances readability and convention - parentheses are most familiar and commonly used, while braces are often reserved for hash references and blocks.
parse_quote_token
Extracts delimiter and content information from quote-like operators such as qw{}
, q{}
, qq{}
, and qx{}
. Handles both bracket pairs (where start and end delimiters differ) and symmetric delimiters (where they're the same).
This parsing is essential for delimiter optimisation, as it separates the operator, delimiters, and content for independent analysis.
find_optimal_delimiter
Determines the best delimiter choice for a quote-like operator by analysing the content for balanced delimiters. Implements the core logic for Rules 1 and 3: choose delimiters that handle unbalanced content gracefully and prefer bracket delimiters.
Only considers bracket delimiters ()
, []
, <>
, {}
as valid options, rejecting exotic delimiters like /
, |
, #
. When multiple delimiters work equally well, uses the preference order to break ties.
check_delimiter_optimisation
Validates that quote-like operators use optimal delimiters according to Rules 1 and 3. This method coordinates parsing the current token and finding the optimal alternative, issuing violations when the current choice is suboptimal.
Acts as a bridge between the parsing and optimisation logic, providing a clean interface for the quote-checking methods.
check_single_quoted
Enforces Rules 1 and 2 for single-quoted strings: prefer double quotes for simple strings unless the content contains literal $
or @
characters that shouldn't be interpolated, or the string contains double quotes that would require special handling.
Also detects when q()
operators would be better than single quotes for complex content, promoting cleaner alternatives.
check_double_quoted
Validates double-quoted strings to ensure they genuinely need interpolation. Suggests single quotes when the content contains only literal $
or @
characters with no actual interpolation, as this indicates the developer intended literal content.
This reduces unnecessary complexity and makes the code's intent clearer.
check_q_literal
Enforces Rules 1 and 3 for q()
operators. First ensures optimal delimiter choice, then evaluates whether simpler quote forms would be more appropriate.
Allows q()
when the content has both single and double quotes (making it the cleanest option), but suggests simpler alternatives for basic content that could use ''
or ""
.
check_qq_interpolate
Enforces Rules 1 and 3 for qq()
operators. First ensures optimal delimiter choice, then determines whether simple double quotes would suffice.
The policy prefers ""
over qq()
when the content doesn't contain double quotes, as this reduces visual noise and follows common Perl conventions.
check_quote_operators
Handles qw()
and qx()
operators, focusing purely on delimiter optimisation according to Rules 1 and 3. These operators don't have simpler alternatives, so the policy only ensures they use the most appropriate delimiters to handle unbalanced content gracefully.
check_use_statement
Checks quoting consistency in use
statements. Enforces that single-argument use statements should use double quotes rather than qw()
, and that multi-argument use statements should always use qw()
. This promotes consistency and clarity in module import statements.
AUTHOR
Paul Johnson <paul@pjcj.net>
COPYRIGHT
Copyright 2025 Paul Johnson.
LICENCE
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.