Quoting Constructs

Writing strings, word lists, and regexes in Perl 6

The Q Lang

Strings are usually represented in Perl 6 code using some form of quoting construct. The most minimalistic of these is Q, usable via the shortcut 「…」, or via Q followed by any pair of delimiters surrounding your text. Most of the time, though, the most you'll need is '…' or "…", described in more detail in the following sections.

Literal strings: Q

Q[A literal string]
More plainly.
Q ^Almost any non-word character can be a delimiter!^
Q 「「Delimiters can be repeated/nested if they are adjacent.」」

Delimiters can be nested, but in the plain Q form, backslash escapes aren't allowed. In other words, basic Q strings are as literal as possible.

Some delimiters are not allowed immediately after Q, q, or qq. Any characters that are allowed in identifiers are not allowed to be used, since in such a case, the quoting construct together with such characters are interpreted as an identifier. In addition, ( ) is not allowed because that is interpreted as a function call. If you still wish to use those characters as delimiters, separate them from Q, q, or qq with a space. Please note that some natural languages use a left delimiting quote on the right side of a string. Q will not support those as it relies on unicode properties to tell left and right delimiters apart.

Q'this will not work!'
Q(this won't work either!)
Q (this is fine, because of space after Q)
Q 'and so is this'
Q<Make sure you <match> opening and closing delimiters>
Q{This is still a closing curly brace → \}

These examples produce:

A literal string
More plainly.
Almost any non-word character can be a delimiter!
Make sure you <match> opening and closing delimiters
This is still a closing curly brace → \

The behaviour of quoting constructs can be modified with adverbs, as explained in detail in later sections.

Short Long Meaning
:x :exec Execute as command and return results
:w :words Split result on words (no quote protection)
:ww :quotewords Split result on words (with quote protection)
:q :single Interpolate \\, \qq[...] and escaping the delimiter with \
:qq :double Interpolate with :s, :a, :h, :f, :c, :b
:s :scalar Interpolate $ vars
:a :array Interpolate @ vars
:h :hash Interpolate % vars
:f :function Interpolate & calls
:c :closure Interpolate {...} expressions
:b :backslash Interpolate \n, \t, etc. (implies :q at least)
:to :heredoc Parse result as heredoc terminator
:v :val Convert to allomorph if possible

Escaping: q

'Very plain';
q[This back\slash stays];
q[This back\\slash stays]# Identical output 
q{This is not a closing curly brace → \}, but this is → };
Q :q $There are no backslashes here, only lots of \$\$\$>!$;
'(Just kidding. There\'s no money in that string)';
'No $interpolation {here}!';
Q:q!Just a literal "\n" here!;

The q form allows for escaping characters that would otherwise end the string using a backslash. The backslash itself can be escaped, too, as in the third example above. The usual form is '…' or q followed by a delimiter, but it's also available as an adverb on Q, as in the fifth and last example above.

These examples produce:

Very plain
This back\slash stays
This back\slash stays
This is not a closing curly brace → } but this is →
There are no backslashes hereonly lots of $$$!
(Just kidding. There's no money in that string)
No $interpolation {here}!
Just a literal "\n" here

Interpolation: qq

my $color = 'blue';
say "My favorite color is $color!"

My favorite color is blue!

The qq form – usually written using double quotes – allows for interpolation of backslash sequences and variables, i.e., variables can be written within the string so that the content of the variable is inserted into the string. It is also possible to escape variables within a qq-quoted string:

say "The \$color variable contains the value '$color'";

The $color variable contains the value 'blue'

Another feature of qq is the ability to interpolate Perl 6 code from within the string, using curly braces:

my ($x, $y, $z) = 4, 3.5, 3;
say "This room is $x m by $y m by $z m.";
say "Therefore its volume should be { $x * $y * $z } m³!";

This room is 4 m by 3.5 m by 3 m.
Therefore its volume should be 42 m³!

By default, only variables with the $ sigil are interpolated normally. This way, when you write "documentation@perl6.org", you aren't interpolating the @perl6 variable. If that's what you want to do, append a [] to the variable name:

my @neighbors = "Felix", "Danielle", "Lucinda";
say "@neighbors[] and I try our best to coexist peacefully."

Felix Danielle Lucinda and I try our best to coexist peacefully.

Often a method call is more appropriate. These are allowed within qq quotes as long as they have parentheses after the call. Thus the following code will work:

say "@neighbors.join(', ') and I try our best to coexist peacefully."

Felix, Danielle, Lucinda and I try our best to coexist peacefully.

However, "@example.com" produces @example.com.

To call a subroutine use the &-sigil.

say "abc&uc("def")ghi";
# OUTPUT: «abcDEFghi␤» 

Postcircumfix operators and therefore subscripts are interpolated as well.

my %h = :1st; say "abc%h<st>ghi";
# OUTPUT: «abc1ghi␤» 

To enter unicode sequences use \x or \x[] with the hex-code of the character or a list of characters.

my $s = "\x[2665] Perl 6!";
dd $s;
# OUTPUT: «Str $s = "I ♥ Perl 6!"␤» 
my $s = "I really \x[2661,2665,2764,1f495] Perl 6!";
dd $s;
# OUTPUT: «Str $s = "I really ♡♥❤💕 Perl 6!"␤» 

You can also use unicode names with \c[].

my $s = "Camelia \c[BROKEN HEART] my \c[HEAVY BLACK HEART]!";
dd $s;
# OUTPUT: «Str $s = "Str $s = "Camelia 💔 my ❤!"␤» 

Interpolation of undefined values will raise a control exception that can be caught in the current block with CONTROL.

sub niler {Nil};
my Str $a = niler;
say("$a.html""sometext");
say "alive"# this line is dead code 
CONTROL { .die };

Word quoting: qw

qw|! @ # $ % ^ & * \| < > | eqv '! @ # $ % ^ & * | < >'.words.list
q:w { [ ] \{ \} } eqv ('[', ']', '{', '}')
Q:w | [ ] { } | eqv ('[', ']', '{', '}')

The :w form, usually written as qw, splits the string into "words". In this context, words are defined as sequences of non-whitespace characters separated by whitespace. The q:w and qw forms inherit the interpolation and escape semantics of the q and single quote string delimiters, whereas Qw and Q:w inherit the non-escaping semantics of the Q quoter.

This form is used in preference to using many quotation marks and commas for lists of strings. For example, where you could write:

my @directions = 'left''right,''up''down';

It's easier to write and to read this:

my @directions = qw|left right up down|;

Word quoting: < >

<a b c> eqv ('a', 'b', 'c');   # OUTPUT: «True␤»
<a b 42> eqv ('a', 'b', '42'); # OUTPUT: «False␤», the 42 become an IntStr allomorph
say < 42 > ~~ Int; # OUTPUT: «True␤»
say < 42 > ~~ Str; # OUTPUT: «True␤»

The angle brackets quoting is like qw, but with extra feature that lets you construct allomorphs or literals of certain numbers:

say <42 4/2 1e6 1+1i abc>.perl;
# OUTPUT: «(IntStr.new(42, "42"), RatStr.new(2.0, "4/2"), NumStr.new(1000000e0, "1e6"), ComplexStr.new(<1+1i>, "1+1i"), "abc")␤» 

To construct a Rat or Complex literal, use angle brackets around the number, without any extra spaces:

say <42/10>.^name;   # OUTPUT: «Rat␤» 
say <1+42i>.^name;   # OUTPUT: «Complex␤» 
say < 42/10 >.^name# OUTPUT: «RatStr␤» 
say < 1+42i >.^name# OUTPUT: «ComplexStr␤» 

Compared to 42/10 and 1+42i, there's no division (or addition) operation involved. This is useful for literals in routine signatures, for example:

sub close-enough-π (<355/113>{
    say "Your π is close enough!"
}
close-enough-π 710/226# OUTPUT: «Your π is close enough!␤» 
 
# WRONG: can't do this, since it's a division operation 
 
sub compilation-failure (355/113{}

Word quoting with quote protection: qww

The qw form of word quoting will treat quote characters literally, leaving them in the resulting words:

say qw{"a b" c}.perl# OUTPUT: «("\"a", "b\"", "c")␤» 

Thus, if you wish to preserve quoted sub-strings as single items in the resulting words you need to use the qww variant:

say qww{"a b" c}.perl# OUTPUT: «("a b", "c")␤» 

Word quoting with interpolation: qqw

The qw form of word quoting doesn't interpolate variables:

my $a = 42say qw{$a b c};  # OUTPUT: «$a b c␤» 

Thus, if you wish for variables to be interpolated within the quoted string, you need to use the qqw variant:

my $a = 42;
my @list = qqw{$a b c};
say @list;                # OUTPUT: «42 b c␤» 

Note that variable interpolation happens before word splitting:

my $a = "a b";
my @list = qqw{$a c};
.say for @list# OUTPUT: «a␤b␤c␤» 

Word quoting with interpolation and quote protection: qqww

The qqw form of word quoting will treat quote characters literally, leaving them in the resulting words:

my $a = 42say qqw{"$a b" c}.perl;  # OUTPUT: «("\"42", "b\"", "c")␤» 

Thus, if you wish to preserve quoted sub-strings as single items in the resulting words you need to use the qqww variant:

my $a = 42say qqww{"$a b" c}.perl# OUTPUT: «("42 b", "c")␤» 

or equivalently:

my $a = 42say <<"$a b" c>>.perl;   # OUTPUT: «("42 b", "c")␤» 
my $a = 42say «"$a b" c».perl;     # OUTPUT: «("42 b", "c")␤» 

Quote protection happens before interpolation, and interpolation happens before word splitting, so quotes coming from inside interpolated variables are just literal quote characters:

my $a = "1 2";
say qqww{"$a$a}.perl# OUTPUT: «("1 2", "1", "2")␤» 
my $b = "\"2 3\"";
say qqww{"$b$b}.perl# OUTPUT: «("1 \"2 3\"", "1", "\"2", "3\"")␤» 

Shell quoting: qx

To run a string as an external program, not only is it possible to pass the string to the shell or run functions but one can also perform shell quoting in a similar manner to the backticks a.k.a. qx in Perl 5. There are some subtleties to consider, however. The backticks are no longer used for shell quoting in Perl 6 and the qx quotes don't interpolate Perl variables. Thus

my $world = "there";
say qx{echo "hello $world"}

prints simply hello. Nevertheless, if you have declared an environment variable before calling perl6, this will be available within qx, for instance

WORLD="there" perl6
> say qx{echo "hello $WORLD"}

will now print hello there.

The result of calling qx is returned, so this information can be assigned to a variable for later use:

my $output = qx{echo "hello!"};
say $output;    # OUTPUT: «hello!␤» 

See also shell, run and Proc::Async for other ways to execute external commands.

Shell quoting with interpolation: qqx

If one wishes to use the content of a Perl variable within an external command, then the qqx shell quoting construct should be used (this corresponds to Perl 5's qx):

my $world = "there";
say qqx{echo "hello $world"};  # OUTPUT: «hello there␤» 

Again, the output of the external command can be kept in a variable:

my $word = "cool";
my $option = "-i";
my $file = "/usr/share/dict/words";
my $output = qqx{grep $option $word $file};
# runs the command: grep -i cool /usr/share/dict/words 
say $output;      # OUTPUT: «Cooley␤Cooley's␤Coolidge␤Coolidge's␤cool␤...» 

See also shell and run for other ways to execute external commands.

Heredocs: :to

A convenient way to write multi-line string literals are heredocs, which let you choose the delimiter yourself:

say q:to/END/; 
Here is
some multi-line
string
END

The contents of the heredoc always begin on the next line, so you can (and should) finish the line.

my $escaped = my-escaping-function(q:to/TERMINATOR/language => 'html'); 
Here are the contents of the heredoc.
Potentially multiple lines.
TERMINATOR

If the terminator is indented, that amount of indention is removed from the string literals. Therefore this heredoc

say q:to/END/; 
    Here is
    some multi line
        string
    END

produces this output:

Here is
some multi line
    string
 
 

Heredocs include the newline from before the terminator.

To allow interpolation of variables use the qq form, but you will then have to escape meta characters {\ as well as $ if it is not the sigil for a defined variable. For example:

my $f = 'db.7.3.8';
my $s = qq:to/END/; 
option \{
    file "$f";
};
END
say $s;

would produce:

option {
    file "db.7.3.8";
};

You can begin multiple Heredocs in the same line.

my ($first$second= qq:to/END1/qq:to/END2/; 
  FIRST
  MULTILINE
  STRING
  END1
   SECOND
   MULTILINE
   STRING
   END2 

Regexes

For information about quoting as applied in regexes see the regular expression documentation.