NAME

Perl::Critic::Policy::ValuesAndExpressions::RequireConsistentQuoting - Use consistent and optimal quoting

VERSION

version v0.1.2

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 "" or qw( )

  • 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() and qq() equivalents when possible

  • Double 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.