Perl Part I · Module 4 · Strings and Text
q, qq and qw: Alternative Quoting
Chapter 4.1 settled which quote character to use, which immediately creates a problem: what do you do when the text itself contains that character? Escaping works and gets ugly fast, and a string carrying both quote marks and backslashes becomes genuinely hard to read. Perl's answer is to let you choose the delimiter — q for a literal string, qq for a processed one, with any punctuation you like as the boundary. The third member of the family, qw, builds a list of words without quotes or commas at all, and it is also the construct Perl programmers mistype most often, because typing the commas anyway produces a list of the right length whose values are quietly wrong.
Foundation12 min readPerlPart IFundamentalsStringsQuoting
Part I · Module 4 · Chapter 4.4 · q, qq and qw: Alternative Quoting
1. The Problem With Fixed Delimiters
Chapter 4.1 gave a clear rule: literal text goes in single quotes. Now consider literal text that contains a single quote.
my $msg = 'the tool\'s own report';That works — \' is one of single quotes' two escapes. But add a few more and the string stops being readable:
my $note = 'use \'-f\' to force, or \'-n\' for a dry run';Every quote you care about is now preceded by a backslash you do not. The text is simple; the notation is not.
2. q and qq Let You Choose
use strict;
use warnings;
my $name = "Ravi";
print q(no $interpolation here), "\n";
print qq(yes $name here), "\n";no $interpolation here
yes Ravi hereTwo operators, and the mapping is exact:
| Operator | Equivalent to | Interpolates? |
|---|---|---|
q(...) | '...' | no |
qq(...) | "..." | yes |
One q for one quote mark, two qs for two quote marks — a mnemonic that holds.
The delimiter is whatever punctuation follows the operator. All of these are the same string:
use strict;
use warnings;
print q(slashes /proj/alu/syn), "\n";
print q{braces /proj/alu/syn}, "\n";
print q[brackets /proj/alu/syn], "\n";
print q!bang /proj/alu/syn!, "\n";slashes /proj/alu/syn
braces /proj/alu/syn
brackets /proj/alu/syn
bang /proj/alu/synChoose a delimiter the text does not contain, and no escaping is needed:
use strict;
use warnings;
print q{use '-f' to force, or '-n' for a dry run}, "\n";
print qq{tab:\there}, "\n";use '-f' to force, or '-n' for a dry run
tab: hereThe first line has no backslashes at all and says exactly what it means. The second shows that qq processes escapes just as double quotes do — \t became a tab.
Bracketing delimiters nest
If you use a paired delimiter, Perl tracks the pairs:
use strict;
use warnings;
print q(outer (inner) done), "\n";
print q{braces {nested} ok}, "\n";outer (inner) done
braces {nested} okThe first ) did not end the string, because it closed the ( that opened inside it. This works for (), {}, [] and <>. A non-paired delimiter such as ! or | has no nesting — the first occurrence ends the string.
That makes a paired delimiter the safer default, and q{...} / qq{...} the most common choice in practice.
3. qw Builds a List of Words
use strict;
use warnings;
my @blocks = qw(alu fifo decoder);
print scalar(@blocks), " blocks: ", join(" | ", @blocks), "\n";3 blocks: alu | fifo | decoderqw splits on whitespace and quotes each piece, so qw(alu fifo decoder) is exactly ('alu', 'fifo', 'decoder') with eleven fewer characters of punctuation.
Arrays belong to Module 5 — here the array is just the destination, and scalar() from Chapter 2.10 and join from Chapter 4.7 are the measuring instruments.
The name follows the pattern: quote words.
4. The Comma Trap
This is the section to remember.
use strict;
use warnings;
my @blocks = qw(alu, fifo, decoder);
print scalar(@blocks), " blocks: ", join(" | ", @blocks), "\n";3 blocks: alu, | fifo, | decoderPossible attempt to separate words with commas at comma-trap.pl line 4.Read the values. The list has three elements, and two of them end in a comma: alu, and fifo,. The third, decoder, does not.
This is the shape of the bug:
- The count is correct. Any check that counts the list — "did I get three blocks?" — passes.
- The values are wrong, but only some of them. The last word is clean. So a comparison against
"alu"fails while a comparison against"decoder"succeeds, which looks like a problem with specific data rather than with the list. use warningscatches it, and the message is unusually direct about what you probably meant.
The cause is simply that qw splits on whitespace and nothing else. A comma is not whitespace, so it is part of the word — the same way qw(a-b c) gives you a-b as one word, which is useful and expected.
5. qw Does Not Interpolate
use strict;
use warnings;
my $prefix = "alu";
my @names = qw($prefix fifo);
print join(" | ", @names), "\n";$prefix | fifoThe first element is the four characters $prefix, not alu.
qw is the list analogue of single quotes, and there is no interpolating version of it. When the list needs a variable in it, use an ordinary list with the quoting you need:
use strict;
use warnings;
my $prefix = "alu";
my @names = ("${prefix}_top", "fifo");
print join(" | ", @names), "\n";alu_top | fifoNote the braces, for the reason Chapter 4.2 §3 established — without them $prefix_top would be a name that does not exist.
6. Why This Matters in Engineering Work
Lists of names are everywhere. Block names, test names, corner names, tool names, required fields in a report. qw(alu fifo decoder regfile) is the clearest way to write one, and it is clearer than the quoted-and-comma'd form precisely because there is less punctuation to misread.
Paths and patterns stop needing escapes. q{/proj/alu/syn/out.v} and q{C:\runs\nightly} are literal, readable, and immune to Chapter 4.1 §2's corruption. A q{...} around any literal path is a small habit with no downside.
Messages containing quotes. Usage text and error messages routinely quote flag names. q{use '-f' to force} is readable; the backslash version is not.
The comma trap costs real time, because the symptom is wrong behaviour on some list entries and not others — which sends you looking at the data rather than at the list literal. Printing the list once at the point you write it is the whole defence.
7. Common Mistakes
Typing commas inside qw. They become part of the words, the count stays right, and the last word is unaffected. §4 measures it.
Expecting qw to interpolate. It does not, and there is no version that does.
Choosing a delimiter the text contains. q!use -n!now! ends at the second !. Pick one the text lacks, and prefer a paired delimiter.
Assuming a non-paired delimiter nests. Only (), {}, [] and <> track pairs.
Using qq for a literal path. qq processes escapes exactly as double quotes do, so it has Chapter 4.1's hazard. Use q for literals.
Reaching for q when plain quotes are fine. q{hello} is not an improvement on 'hello'. These operators earn their place when the text contains the delimiter you would otherwise use.
8. Exercise
Exercise 1 — replace the escapes. Rewrite 'use \'-f\' to force, or \'-n\' for a dry run' using q with a delimiter that needs no escaping. Confirm the output is identical to the original.
Exercise 2 — the comma trap, measured. Run the §4 script. Record the element count, the three values and the warning. Then write one sentence explaining why a check on the count would not have caught this.
Exercise 3 — find the trap in a loop. Write a loop over qw(alu, fifo, decoder) that prints looking for <name>.log for each. Record all three lines and say which two filenames are wrong and why the third is not.
Exercise 4 — q versus qq. Predict what each prints, then run them: q{path is /a/b and cost $5}, qq{path is /a/b and cost \$5}, q{tab:\there}, qq{tab:\there}. Say which two differ from their partner and why.
Exercise 5 — nesting. Predict the output of print q(a (b) c), "\n"; and print q!a !b! c!, "\n"; before running them. Explain the difference using §2.
Exercise 6 — an interpolating word list. Given my $blk = "fifo";, build a list containing fifo_wr, fifo_rd and common — first try it with qw, record what you get, then write the version that works and say why qw could not.
9. Summary
q(...)is'...'andqq(...)is"..."— oneqfor one quote mark, two for two.- The delimiter is yours to choose, so text containing quotes or backslashes needs no escaping.
- Paired delimiters nest —
(),{},[],<>— and non-paired ones do not. Preferq{...}. qw(...)builds a list of whitespace-separated words, each implicitly single-quoted.- Commas inside
qwbecome part of the words. The count stays correct and only the last word is clean, which is why the bug reads as a data problem.use warningsreports it. qwdoes not interpolate, and there is no interpolating form — use an ordinary list.- Print a
qwlist once when you write it. A stray comma is invisible in the source and obvious in the output.
That completes the quoting group. Chapter 4.5 moves from writing strings to examining them: measuring their length, finding a piece inside one, and extracting or replacing part of it — with no pattern matching involved.
Where this fits
Part of the Perl curriculum.
