SCALARs and strings

qq//#

Build a double-quoted, interpolated string with a delimiter you pick.

qq// is the long form of the "..." string literal. It produces the same string "" would, so qq/hello $name\n/ and "hello $name\n" are interchangeable. The point of qq is the delimiter: when the content contains " (or backslash sequences that would interfere with double quotes), you pick a different delimiter and keep the string readable instead of threading \" through it.

Synopsis#

qq/STRING/
qq{STRING}
qq(STRING)
qq[STRING]
qq<STRING>
qqXSTRINGX        # any non-word, non-whitespace char works as delimiter

What you get back#

A scalar string. Variables referenced inside are interpolated at the point qq// is evaluated (not at parse time); backslash escape sequences are expanded. The result has no implicit newline — you have to write \n yourself.

Choosing a delimiter#

Any character that is not a word character (/\w/) and not whitespace may follow qq. The four bracket pairs nest:

qq(foo (bar) baz)          # "foo (bar) baz" — inner () balanced
qq{ if ($x) { 1 } else { 0 } }
qq[a[b[c]d]e]
qq<<a<b>c>>

Non-bracketing delimiters use the same character at both ends and do not nest:

qq|one|two|                # SYNTAX ERROR — first | closes
qq/a\/b/                   # "a/b"  backslash escapes the delimiter

If the delimiter is a word character, whitespace between qq and the delimiter is required:

qq XfooX                   # OK — "foo"
qqXfooX                    # WRONG — parsed as identifier qqXfooX

# as delimiter needs no space and is occasionally handy for strings containing every other punctuation mark:

qq#He said "hi" & waved.#  # "He said \"hi\" & waved."

The extra_paired_delimiters feature (5.36+) recognises a wide set of Unicode bracket pairs as nesting delimiters; enable it with use feature 'extra_paired_delimiters' when you want, say, guillemets or CJK brackets.

What gets interpolated#

  • Scalars: $x, $hash{key}, $array[0], $ref->{k}[2].

  • Arrays: @arr expands in order, elements joined by $" (default " "). Equivalent to join $", @arr.

  • Slices: @h{qw(a b)}, @a[1..3].

  • Dereferences with arrows and subscripts: $ref->{key}[0].

What is not interpolated:

  • Method calls: $obj->meth inside qq// interpolates $obj and leaves the literal text ->meth in the string.

  • Function calls: @{[ func() ]} is the usual workaround — array reference dereference runs arbitrary code and splices its result in.

  • Punctuation arrays other than @_, @+, @-: only interpolate when braced (@{*}). Bare @* is a literal @*.

my $obj = Some::Class->new;
qq/$obj->name/;                       # interpolates $obj, leaves "->name"
qq/@{[ $obj->name ]}/;                # calls the method, interpolates result

Escape sequences#

Available inside qq// (and anywhere else interpolation happens):

Sequence

Meaning

\t

tab (HT)

\n

newline (platform-virtual line terminator)

\r

carriage return (CR)

\f

form feed (FF)

\b

backspace (BS)

\a

alarm / bell (BEL)

\e

escape (ESC)

\0

NUL

\\

literal backslash

\"

literal double quote

\x1b

hex char, 0x00–0xFF

\x{263A}

hex char, any codepoint (braced form)

\o{23072}

octal char, any codepoint

\033

octal char, 000–777 (prefer \o{})

\cA

control char — 64 xor’d with uppercased next char

\N{GREEK SMALL LETTER ALPHA}

named Unicode char (needs use charnames)

\N{U+03B1}

Unicode char by codepoint (always Unicode, even on EBCDIC)

Case and quoting modifiers apply until \E or end of string:

Sequence

Meaning

\l

lowercase the next character only

\u

titlecase (not uppercase!) the next character only

\L

lowercase until \E

\U

uppercase until \E

\F

foldcase until \E

\Q

quote regex metacharacters until \E (calls quotemeta)

\E

end the most recent \L / \U / \F / \Q

\L, \U, \F, \Q stack — each needs its own \E.

say "\u$name";                        # capitalise first letter
say "\U$name\E's account";            # uppercase $name, rest untouched
say "match $file literally: \Q$file\E";

\Q inside qq// is applied after interpolation, so qq/\Q$pat\E/ equals quotemeta($pat). (In regex quote operators qr// and m//, \Q is applied after interpolation but before regex compilation — the difference matters when $pat itself contains regex metacharacters you want to keep literal.)

Perl has no \v escape in string literals — it is a regex metacharacter. Use \x0b, \cK, or \N{VT} for a vertical tab.

Global state it touches#

  • $" — list separator used when interpolating arrays and slices. Default " ". Change with local $" = "," for one scope.

No other interpreter globals participate in qq// evaluation itself. Interpolated variables are of course whatever their current values are at the point qq// runs.

Examples#

Plain interpolation, identical in meaning to the "..." form:

my $name = "world";
my $s = qq/hello, $name!\n/;          # "hello, world!\n"

String that contains double quotes — qq with a different delimiter avoids backslash litter:

my $msg = qq{He said "yes" and then "maybe".};
# vs:   "He said \"yes\" and then \"maybe\"."

Multi-line HTML snippet with nested braces — the () pair nests:

my $user = "rj";
my $html = qq(
  <p>Welcome, $user.</p>
  <p>You have @{[ scalar @inbox ]} messages.</p>
);

Array interpolation with a custom separator:

my @tags = qw(perl rust docs);
local $" = ", ";
say qq/tags: @tags/;                  # "tags: perl, rust, docs"

Method-call trap — -> is literal inside qq//:

my $obj = File::Spec->new;
qq/path is $obj->rel2abs('.')/;       # "path is <stringified $obj>->rel2abs('.')"
qq/path is @{[ $obj->rel2abs('.') ]}/;
                                      # actually calls rel2abs()

Building an SQL fragment where $ident is untrusted — \Q..\E keeps embedded %, _, and backslashes literal under a LIKE clause only after you have handled proper parameterisation; for actual SQL escaping use the driver’s quoting, not \Q:

my $needle = "100% sure";
my $pat = qq/\Q$needle\E/;            # the regex-safe form
# $pat eq "100\\%\\ sure"

Stacked modifiers:

say qq/\Qfoo \ubar \Ubaz\E qux\E done/;
# "foo\ Bar\ BAZ qux done"
#  \Q quotes spaces/?; \u titlecases b; \U uppercases baz until \E;
#  outer \E ends \Q.

Edge cases#

  • Parse-time delimiter choice. Perl picks the closing delimiter the moment it reads the opening one. qq/.../ expects a /; there is no way to switch mid-string. If you need both kinds of braces, pick a non-bracket delimiter.

  • Backslash at end of string with non-bracket delimiter. qq/a\/ is a/ (backslash escapes the delimiter, string continues); to get a literal trailing backslash, change delimiter: qq{a\\}.

  • No nesting for non-bracket delimiters. qq|a|b| is the string a followed by the identifier b followed by | — a syntax error in most contexts. Pick bracket delimiters when the content contains the delimiter char.

  • # as delimiter is a special case only because of how comments interact: qq#...# is a string, but qq #...# (with whitespace) is the operator qq followed by a comment, with the string taken from the next line. This mirrors the behaviour of all q-family operators.

  • Empty string. qq// is the empty string, same as "".

  • Interpolated undef. Stringifies to the empty string and, under use warnings, triggers an uninitialized warning at the point of interpolation, not at the point $var was assigned undef.

  • $ or @ followed by non-identifier. Stays literal: qq/cost: \$5/ and qq/cost: $5/ both produce cost: $5 (there is no variable named $5 in the Perl 5 identifier sense — $5 is a regex capture, which does exist, so the second form interpolates capture group 5, whatever it currently is). For a literal $ or @, escape it: \$, \@.

  • \N{...} without charnames. Named characters require use charnames ':full' (or similar) to be loaded in scope; without it you get a compile-time error. \N{U+HEX} and the single-name forms in the :loose set work without it.

  • Locale-sensitive case mapping. With use locale including LC_CTYPE, \l, \u, \L, \U use the current locale’s case tables. Without it, Unicode case tables are used for codepoints above 0xFF, and ASCII rules below. \F uses Unicode foldcase regardless of locale (except under a UTF-8 locale, where it matches \L).

  • One level only. The result of interpolation is not re-scanned. my $v = '$x'; qq/$v/ is the four-character string $x, not the value of $x.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • q// — single-quoted literal, no interpolation, same delimiter rules

  • qw// — word-list literal, produces a list of strings split on whitespace

  • qx// — interpolated string executed as a shell command, captures stdout

  • qr// — interpolated regex, compiled once and reusable

  • sprintf — reach for this when the work is formatting numbers or padding fields, not splicing variables into text

  • quotemeta — the function \Q..\E calls

  • join — what array interpolation is secretly doing, with $" as the separator

  • $" — list separator used when an array interpolates into a double-quoted string

  • Quote and Quote-like Operators — the full table of q, qq, qx, qw, qr, m, s, tr and their shared delimiter and escape rules