Chapter 4. Strings

Strings represent the text data in your program as Str objects. Perl 6’s facility with text data and its manipulation is one of its major attractions. This chapter focuses on the many ways that you can create Strs; for any job you have there’s likely a feature that makes that easy for you. Along with that you’ll see a bit about inspecting, extracting, and comparing text in preparation for loftier goals coming up.

Literal Quoting

You can type literal text directly into your program. What you type is what the text is, and the compiler does not interpret it as anything other than exactly what you typed. You can surround literal text with half-width corner brackets, and :

「Literal string」

This is your first encounter with a paired delimiter. These characters mark the beginning and end of the Str. There’s an opening character and a closing character that surround your text.

Any character that you use is interpreted as exactly what it is, with no special processing:

「Literal '" string with \ and {} and /」

You can’t use only one of the delimiter characters in the Str. These won’t work:

「 Unpaired 「 Delimiters 」
「 Unpaired 」 Delimiters 」

However, if you pair delimiters in the text the compiler will figure out if they are balanced—the opening delimiter comes first and a closing delimiter pairs with it:

「 Del「i」miters 」
Note

The Perl 6 language is a collection of sublanguages, or slangs. Once inside a particular slang the compiler parses your source code by that slang’s rules. The quoting language is one of those slangs.

If your literal text has corner brackets in it you can use a generalized quoting mechanism. These start with a Q (or q) and can get as limiting or as permissive as you like, as you’ll see in this chapter.

After the Q you can select almost any character to be the delimiter. It can’t be a character valid in a variable name, because that would make it look like a name instead of a delimiter. The paired characters are common; the opening character has to be on the left and its closing partner has to be on the right. Perhaps you want to use square brackets instead of corner brackets. Now the isn’t special because it’s not a delimiter:

Q[Unpaired 」 Delimiters]

Most of the paired characters act the same:

Q{Unpaired 」 Delimiters}
Q<Unpaired 」 Delimiters>
Q<<Unpaired 」 Delimiters>>
Q«Works»

There’s one exception. You can’t have an open parenthesis right after the Q because that makes it look like a subroutine call (but it’s not):

Q(Does not compile)

You don’t have to use paired characters. You can use the same character for the opening and closing delimiter:

Q/hello/

You can store a Str in a variable or output it immediately:

my $greeting = Q/Hello World!/;
put Q/Hello World!/;

And you can call methods on your Str just like you could do with numbers:

Q/Hello World!/.^name;  # Str
Q/Hello World!/.put;

Escaped Strings

One step up from literal Strs are escaped strings. The single tick acts as the delimiter for these Strs. These are often called single-quoted strings:

% perl6
> 'Hamadryas perlicus'
Hamadryas perlicus

If you want to have the single tick as a character in the Str you can escape it with a backslash. That tells the quoting slang that the next character isn’t the delimiter but belongs as literal text:

% perl6
> 'The escaped \' stays in the string'
The escaped ' stays in the string

Since the \ is the escape character, you can escape it to get a literal backslash:

% perl6
> 'Escape the \\ backslash'
Escape the \ backslash

A DOS path can be quite annoying to type, but escaped and literal Strs take care of that:

% perl6
> 'C:\\Documents and Settings\\Annoying\\Path'
C:\Documents and Settings\Annoying\Path
> Q/C:\Documents and Settings\Annoying\Path/
C:\Documents and Settings\Annoying\Path

If you want to use a different delimiter for an escaped string you use the lowercase q followed by the delimiter that you want (following the same rules as for the literal quoting delimiters):

q{Unpaired ' Delimiters}
q<Unpaired ' Delimiters>
q<<Unpaired ' Delimiters>>
q«Works»

Adverbs for Quoting

Adverbs modify how something works and are a big part of Perl 6. You’ll see more of these in Chapter 9, but you’ll get a taste for them in this chapter. Adverbs start with a colon followed by letters or numbers.

All of the quoting methods you’ll see in this chapter are modifications of basic literal quoting. You use adverbs to adjust the quoting behavior.

The :q adverb modifies Q to become an escaping quote. There must be some whitespace after the adverb, but it’s optional after the Q:

% perl6
> Q:q 'This quote \' escapes \\'
This quote ' escapes \
> Q :q 'This quote \' escapes \\'
This quote ' escapes \

This form doesn’t specifically escape the single tick; it escapes the backslash and the delimiter characters. A backslash that doesn’t precede a delimiter or another backslash is interpreted as a literal backslash:

% perl6
> Q :q  「This quote \' escapes」
This quote \' escapes
> Q :q  「This quote \「 escapes」
This quote 「 escapes
> Q :q  「This quote \「\」 escapes」
This quote 「」 escapes

The :single adverb is a longer version of :q and might help you remember what you want:

% perl6
> Q :single 'This quote \' escapes'
This quote ' escapes

Most of the time you aren’t going to work this hard. The common uses of quoting have default delimiters so you don’t even see the Q. Even though many Strs would be more correctly represented with strict literal quoting, most people tend to use the single ticks simply because it’s easier to type. No matter which quoting method you use you get the same type of object.

String Operators and Methods

Use the concatenation operator, ~, to combine Strs. Some people call this “string addition.” The output shows the two Strs as one with nothing else between them:

my $name = 'Hamadryas' ~ 'perlicus';
put $name;      # Hamadryasperlicus

You could add a space yourself by putting it in one of the Strs, but you can also concatenate more than two Strs at a time:

put 'Hamadryas ' ~ 'perlicus';
put 'Hamadryas' ~ ' ' ~ 'perlicus';

The join routine glues together Strs with the first Str you give it:

my $butterfly-name = join ' ', 'Hamadryas', 'perlicus'

You can make larger Strs by repeating a Str. The x is the Str replication operator. It repeats the Str the number of times you specify. This is handy for making a text-based divider or ruler for your output:

put '-' x 70;
put '.123456789' x 7;

The .chars methods tells you how many characters are in the Str:

put 'Hamadryas'.chars;  # 9

Any Str with at least one character is True as a Boolean, including the Str of the single character 0:

put ?'Hamadryas';       # True
put ?'0';               # True

The empty string has no characters. It consists only of the opening delimiter and the closing delimiter. It’s False as a Boolean:

put ''.chars;           # 0
put ?'';                # False

Be careful that when you test a Str you test the right thing. A Str type object is also False, but .DEFINITE can tell them apart:

put ''.DEFINITE         # True
put Str.DEFINITE        # False

This is handy in a conditional expression where you don’t care what the Str is (empty, '0', or anything else) as long as it’s not a type object:

given $string {
    when .DEFINITE {
        put .chars ?? 'Has characters' !! 'Is empty';
        }
    default { put 'Type object' }
    }

The .lc method changes all the characters in a Str to lowercase, and .uc changes them to uppercase:

put 'HaMAdRyAs'.lc;     # hamadryas
put 'perlicus'.uc;      # PERLICUS

The .tclc method uses title case, lowercasing everything then capitalizing the first character of the Str:

put 'hamadryas PERLICUS'.tclc;    # Hamadryas perlicus

Looking Inside Strings

You can also inspect a Str to find out things about it. The .contains method returns a Boolean value indicating whether it finds one Str—the substring—inside the target Str:

% perl6
> 'Hamadryas perlicus'.contains( 'perl' )
True
> 'Hamadryas perlicus'.contains( 'Perl' )
False

Instead of parentheses you can put a colon followed by the substring to search for:

% perl6
> 'Hamadryas perlicus'.contains: 'perl'
True
> 'Hamadryas perlicus'.contains: 'Perl'
False

The .starts-with and .ends-with methods do the same thing as .contains but require the substring to appear at a particular location:

> 'Hamadryas perlicus'.starts-with: 'Hama'
True
> 'Hamadryas perlicus'.starts-with: 'hama'
False
> 'Hamadryas perlicus'.ends-with: 'us'
True

These methods are case sensitive. The case of each character in the substring must match the case in the target Str. If it’s uppercase in the substring it must be uppercase in the target. If you want case insensitivity you can use .fc to make a “caseless” Str. This “case folding” method is especially designed for comparisons:

> 'Hamadryas perlicus'.fc.starts-with: 'hama'
True

.fc also knows about equivalent characters such as the ss and the sharp ß. The method doesn’t change the text; it evaluates to a new Str based on a long list of rules about equivalence defined by Unicode. You should case fold both the target and substrings if you want to allow these sorts of variations:

> 'Reichwaldstrasse'.contains: 'straße'
False
> 'Reichwaldstrasse'.fc.contains: 'straße'
False
> 'Reichwaldstrasse'.contains: 'straße'.fc
True
> 'Reichwaldstrasse'.fc.contains: 'straße'.fc
True

.substr extracts a substring by its starting position and length inside the Str. The counting starts with zero at the first character:

put 'Hamadryas perlicus'.substr: 10, 4;     # perl

The .index method tells you where it finds a substring inside the larger Str (still counting from zero), or returns Nil if it can’t find the substring:

my $i = 'Hamadryas perlicus'.index: 'p';
put $i ?? 'Found at ' ~ $i !! 'Not in string'; # Found at 10

Use both of them together to figure out where to start:

my $s = 'Hamadryas perlicus';
put do given $s.index: 'p' {
    when Nil { 'Not found' }
    when Int { $s.substr: $_, 4 }
    }

Normal Form Grapheme

Perl 6 is Unicode all the way down. It works on graphemes, which most of us think of as “characters” in the everyday sense. These are the full expression of some idea, such as e, é, or . It expects your source code to be UTF-8 encoded and outputs UTF-8 text. All of these work, although they each represent a different language:

'көпөлөк'
'तितली'
'蝴蝶'
'Con bướm'
'tauriņš'
'πεταλούδα'
'भंबीरा'
'פרפר'

You can use emojis too:

my $string = '';
put $string;

One of the Perl 6 “characters” might be made of up two or more entries in the Universal Character Database (UCD). Perl 6 refers to entries in the UCD as codes and to their composition as a “character.” It’s not the best terminology. In this book, character means grapheme and code point refers to an entry in the UCD.

Why does any of that matter? The .chars method tells you the length of the Str in graphemes. Consider the Hebrew word for “caterpillar.” It has 11 graphemes but 14 code points:

% perl6
> 'קאַטערפּיללאַר'.chars
11
> 'קאַטערפּיללאַר'.codes
14

Why the different counts? There are graphemes such as אַ that are more than one code point (in that case, the two code points are the Hebrew Aleph and patah diacritical mark). Most of the time you won’t care about this. If you do, you can get a list of the code points with .ords:

> 'קאַטערפּיללאַר'.ords
(1511 1488 1463 1496 1506 1512 1508 1468 1497 1500
1500 1488 1463 1512)

String Comparisons

Str objects know if they are relatively greater than, less than, or the same as another Str. Perl 6 uses lexicographic comparison to go through the Strs character by character.

The numbers comparison operators are symbols, but the Strs use operators made up of letters. The eq operator tests if the Strs are exactly equal. Case matters. Every character at each position in the Str must be exactly the same in each Str:

% perl6
> 'Hamadryas' eq 'hamadryas'
False
> 'Hamadryas' eq 'Hamadryas'
True

The gt operator evaluates to True if the first Str is strictly lexicographically greater than the second (ge allows it to be greater than or equal to the second Str). This is not a dictionary comparison, so case matters. The lowercase letters come after the uppercase ones and so are “greater”:

% perl6
> 'Hama' gt 'hama'
False
> 'hama' gt 'Hama'
True

The uppercase letters come before the lowercase ones, so any Str that starts with a lowercase letter is greater than any Str that starts with an uppercase letter:

% perl6
> 'alpha' gt 'Omega'
True
> 'α' gt 'Ω'
True

You can get some weird results if you compare numbers as Strs. The character 2 is greater than the character 1, so any Str starting with 2 is greater than any Str starting with 1:

% perl6
> '2' gt '10'
True

The lt operator evaluates to True if the first Str is lexicographically less than the second (le allows it to be less than or equal to the second Str):

% perl6
> 'Perl 5' lt 'Perl 6'
True

If you don’t care about their case you can lowercase both sides with .lc:

% perl6
> 'Hamadryas'.lc eq 'hamadryas'.lc
True

This wouldn’t work for the Reichwaldstrasse example you saw previously. If you wanted to allow for equivalent representations you’d use .fc:

% perl6
> 'Reichwaldstrasse'.lc eq 'Reichwaldstraße'.lc
False
> 'Reichwaldstrasse'.fc eq 'Reichwaldstraße'.fc
True

As with numbers, you can chain the comparisons:

% perl6
> 'aardvark' lt 'butterfly' lt 'zebra'
True

Prompting for Input

You’ve already used prompt for simple things. When you call it your program reads a single line and chops off the newline that you typed. A small modification of the program shows you what sort of type you get back:

my $answer = prompt( 'What\'s your favorite animal? ' );
put '$answer is type ', $answer.^name;
put 'You chose ', $answer;

When you answer the question you get a Str:

% perl6 prompt.p6
What's your favorite animal? Fox
$answer is type Str
You chose Fox

When you don’t type anything other than a Return the answer is still a Str, but it’s an empty Str:

% perl6 prompt.p6
What's your favorite animal?
$answer is type Str
You chose

You end input with Control-D, which is the same as not typing anything. In that case it returns an Any type object. Notice that the line showing the type appears on the same line as the prompt text—you never typed a Return. There’s also a warning about that Any value, and finally your last line of output:

% perl6 prompt.p6
What's your favorite animal? $answer is type Any
Use of uninitialized value $answer of type Any in string context.
You chose

To guard against this problem you can test $answer. The Any type object is always False. So is the empty Str:

my $answer = prompt( 'What\'s your favorite animal? ' );
put do
    if $answer { 'You chose ' ~ $answer }
    else       { 'You didn\'t choose anything.' }

prompt takes whatever you type, including whitespace. If you put some spaces at the beginning and end that’s what shows up in the Str:

% perl6 prompt.p6
What's your favorite animal?                 Butterfly
You chose                 Butterfly

You can see this better if you put in something to surround the answer portion of the output, such as <> in this example:

my $answer = prompt( 'What\'s your favorite animal? ' );
put do
   if $answer { 'You chose <' ~ $answer ~ '>' }
   else       { 'You didn't choose anything' }

Now you can easily see the extra space in $answer:

% perl6 prompt.p6
What's your favorite animal?                 Butterfly
You chose <                Butterfly            >

The .trim method takes off the surrounding whitespace and gives you back the result:

my $answer = prompt( 'What\'s your favorite animal? ' ).trim;

If you apply it to $answer by itself it doesn’t work:

$answer.trim;

You need to assign the result to $answer to get the updated value:

$answer = $answer.trim;

That requires you to type $answer twice. However, you know about binary assignment so you can shorten that to use the variable name once:

$answer .= trim;

If you don’t want to remove the whitespace from both sides you can use either .trim-leading or .trim-trailing for the side that you want.

Number to String Conversions

You can easily convert numbers to Strs with the .Str method. They may not look like what you started with. These look like number values but they are actually Str objects where the digits you see are characters:

% perl6
> 4.Str
4
> <4/5>.Str
0.8
> (13+7i).Str
13+7i

The unary prefix version of ~ does the same thing:

% perl6
> ~4
4
> ~<4/5>
0.8
> ~(13+7i)
13+7i

If you use a number in a Str operation it automatically converts it to its Str form:

% perl6
> 'Hamadryas ' ~ <4/5>
Hamadryas 0.8
> 'Hamadryas ' ~ 5.5
Hamadryas 5.5

String to Number Conversions

Going from Strs to numbers is slightly more complicated. If the Str looks like a number you can convert it to some sort of number with the unary prefix version of +. It converts the Str to the number of the narrowest form, which you can check with .^name:

% perl6
> +'137'
137
> (+'137').^name
Int
> +'1/2'
0.5
> (+'1/2').^name
Rat

This only works for decimal digits. You can have the decimal digits 0 to 9 and a possible decimal point followed by more decimal digits. An underscore is allowed with the same rules as for literal numbers. The conversion ignores surrounding whitespace:

% perl6
> +' 1234 '
1234
> +' 1_234 '
1234
> +' 12.34 '
12.34

Anything else, such as two decimal points, causes an error:

> +'12.34.56'
Cannot convert string to number: trailing characters after number

When you perform numerical operations on a Str it’s automatically converted to a number:

% perl6
> '2' + 3
5
> '2' + '4'
6
> '2' ** '8'
256

In the previous exercise you should have been able to create a conversion error even though you didn’t have the tools to handle it. If you want to check if a Str can convert to a number you can use the val routine. That gives you an object that does the Numeric role if it can convert the Str. Use the smart match operator to check that it worked:

my $some-value = prompt( 'Enter any value: ' );
my $candidate = val( $some-value );

put $candidate, ' ', do
    if $candidate ~~ Numeric { ' is numeric' }
    else                     { ' is not numeric' }

This seems complicated now because you haven’t read about interpolated Strs yet. It will be much clearer by the end of this chapter.

Sometimes your text is numeric but not decimal. The .parse-base method can convert it for you. It takes a Str that looks like a nondecimal number and turns it into a number:

my $octal  = '0755'.parse-base: 8;     # 493
my $number = 'IG88'.parse-base: 36;    # 860840

This is the same thing the colon form was doing in Chapter 3:

:8<0755>
:36<IG88>

Interpolated Strings

You’ve taken a long path through this chapter to get to the quoting mechanism that you’re likely to use the most. An interpolated string replaces special sequences within the Str with other characters. These Strs will also make easier some of the code you’ve already seen.

Interpolated Strs use the double quote, ", as the default delimiter and are sometimes called double-quoted strings. You need to escape the " if you want one in the Str, and you can escape the \:

% perl6
> "Hamadryas perlicus"
Hamadryas perlicus
> "The escaped \" stays in the string"
The escaped " stays in the string
> "Escape the \\ backslash"
Escape the \ backslash

The backslash also starts other special interpolating sequences. A \t represents a tab character. A \n represents a newline:

put "First line\nSecond line\nThird line";

If you want a character that’s not easy to type you can put its code number (a hexadecimal value) after \x or inside \x[]. Don’t use the 0x prefix; the \x already assumes that:

put "The snowman is \x[2603]";

Several comma-separated code numbers inside \x[] turn into multiple characters:

put "\x[1F98B, 2665, 1F33B]";  # 

If you know the name of the character you can put that inside \c[]. You don’t quote these names and the names are case insensitive:

put "\c[BUTTERFLY, BLACK HEART, TACO]";  # 

Those are nice, but it’s much more handy to interpolate variables. When a double-quoted Str recognizes a sigiled variable name it replaces the variable with its value:

my $name = 'Hamadryas perlicus';
put "The best butterfly is $name";

The quoting slang looks for the longest possible variable name (and not the longest name actually defined). If the text after the variable name looks like it could be a variable name that’s the variable it looks for:

my $name = 'Hamadryas perlicus';
put "The best butterfly is $name-just saying!";

This is a compile-time error:

Variable '$name-just' is not declared

If you need to separate the variable name from the rest of the text in the double-quoted Str you can surround the entire variable in braces:

my $name = 'Hamadryas perlicus';
put "The best butterfly is {$name}-just saying!";

Escape a literal $ where it might look like a sigil that starts a variable name:

put "I used the variable \$name";

Now here’s the powerful part. You can put any code you like inside the braces. The quoting slang will evaluate the code and replace the braces with the last evaluated expression:

put "The sum of two and two is { 2 + 2 }";

This means that the previous programs in this chapter are much easier to type than they first appear. You can construct the Str inside the delimiters rather than using a series of separate Strs:

my $answer = prompt( 'What\'s your favorite animal? ' );
put "\$answer is type {$answer.^name}";
put "You chose $answer";

Like with the previous Strs, you can choose a different delimiter for interpolated Strs. Use qq (double q for double quoting) in front of the delimiter:

put qq/\$answer is type {$answer.^name}/;

The \n is interpolated as a newline and the \t becomes a tab:

put qq/\$answer is:\n\t$answer/;

This Str has two lines and the second one is indented:

answer is:
    Hamadryas perlicus

qq// is the same as Q with the :qq or :double adverb:

put Q :qq /\$answer is type {$answer.^name}/;
put Q :double /\$answer is type {$answer.^name}/;

If you want to interpolate only part of a Str you can use \qq[] for that part:

my $genus = 'Hamadryas';
put '$genus is \qq[$genus]';

Going the other way, you can turn off interpolation for part of a Str by making that part act like a single-quoted Str with \q[]:

put "\q[$genus] is $genus";

Table 4-1 shows many other special sequences available inside a double-quoted context.

Table 4-1. Selected backslash-escape sequences
Escape sequenceDescription
\aThe ASCII bell character
\bBackspace
\rCarriage return
\nNewline
\tTab
\fForm feed
\c[NAME]Character by name
\q[…]Single quote the part inside the brackets
\qq[…]Double quote the part inside the brackets
\x[ABCD]Character by code number in hex

Here Docs

For multiline quoting you could use the quoting you’ve seen so far, but every character between those delimiters matters. This often results in ugly outdenting:

my $multi-line = '
    Hamadryas perlicus: 19
    Vanessa atalanta: 17
    Nymphalis antiopa: 0
    ';

Interpolating \n doesn’t make it any prettier:

my $multi-line = "Hamadryas perlicus: 19\n...";

A here doc is a special way of quoting a multiline text. Specify a delimiter with the :heredoc adverb. The Str ends when the slang finds that same Str on a line by itself:

my $multi-line = q :heredoc/END/;
    Hamadryas perlicus: 19
    Vanessa atalanta: 17
    Nymphalis antiopa: 0
    END

put $multi-line;

This also strips the same indentation it finds before the closing delimiter. The output ends up with no indention even though it had it in the literal code:

Hamadryas perlicus: 19
Vanessa atalanta: 17
Nymphalis antiopa: 0

The :to adverb does the same thing as :heredoc:

my $multi-line = q :to<HERE>;
    Hamadryas perlicus: 19
    Vanessa atalanta: 17
    Nymphalis antiopa: 0
    HERE

This works with the other quoting forms too:

put Q :to/END/;
    These are't special: $ \
    END

put qq :to/END/;
    The genus is $genus
    END

Shell Strings

Shell strings are the same sort of quoting that you’ve seen so far, but they don’t construct a Str to store in your program. They create an external command to run in the shell. A shell string captures the command’s output and gives it to you. Chapter 19 covers this, but here’s something to get you started.

qx uses the same rules as escaped Strs. The hostname command works on both Unix and Windows systems:

my $uname = qx/hostname/;
put "The hostname is $uname";
put "The hostname is { qx/hostname/ }"; # quoting inside quoting

In this output there’s a blank line between the lines because it includes the newline in the normal command output:

The hostname is hamadryas.local

The hostname is hamadryas.local

Use .chomp to fix that. If there’s a newline on the end of the text it removes it (although put adds its own):

my $uname = qx/hostname/.chomp;
put "The hostname is $uname";
put "The hostname is { qx/hostname/.chomp }";

print doesn’t add a newline for you, so you don’t need to remove the one from the command output:

print "The hostname is { qx/hostname/ }";

qx and qqx are shortcuts for single and double quoting Strs with the :x or :exec adverbs:

print Q :q      :x    /hostname/;
print Q :q      :exec /hostname/;
print Q :single :exec /hostname/;

Shell Safety

In the previous examples, the shell looks through its PATH environment variable to find the hostname command and executes the first one that it finds. Since people can set their PATH (or something can set it for them), you might not get the command you expect. If you use an absolute path you don’t have this problem. Literal quoting is handy to avoid inadvertent escaping:

put Q :x '/bin/hostname';
put Q :x 'C:\Windows\System32\hostname.exe'
Note

I won’t cover secure programming techniques here, but I do write more about these problems in Mastering Perl. Although that’s a Perl 5 book, the risks to your program are the same.

Although you have not seen hashes yet (Chapter 9), you could change the environment for your program. If you set PATH to the empty Str your program won’t be able to search for any programs:

%*ENV<PATH> = '';
print Q :x 'hostname';       # does not find this
print Q :x '/bin/hostname';  # this works

If that’s too restrictive you can set the PATH to exactly the directories that you consider safe:

%*ENV<PATH> = '/sbin:/usr/local/bin';
print Q :x 'hostname';       # does not find this
print Q :x '/bin/hostname';  # this works

There’s also a double-quoted form of shell Strs:

my $new-date-string = '...';
my $output = qqx/date $new-date-string/

What’s in that $new-date-string? If it descends from user data, external configuration, or something else that you don’t control, you might be in for a surprise. That could be malicious or merely accidental, so be careful:

my $new-date-string = '; /bin/rm -rf';
my $output = qqx/date $new-date-string/

Fancier Quoting

You can combine adverbs in generalized quoting to use just the features that you need. Suppose that you want to interpolate only things in braces but nothing else. You can use the :c adverb:

% perl6
> Q :c "The \r and \n stay, but 2 + 2 = { 2 + 2 }"
The \r and \n stay, but 2 + 2 = 4

To get only variable interpolation use the :s adverb. No other processing happens:

% perl6
> my $name = 'Hamadryas'
Hamadryas
> Q :s "\r \n { 2 + 2 } $name"
\r \n { 2 + 2 } Hamadryas

You can combine adverbs to get any mix of features that you like. Cluster the adverbs or space them out. They work the same either way:

% perl6
> Q :s:c "\r \n { 2 + 2 } $name"
\r \n 4 Hamadryas
> Q :s:c:b "\r \n { 2 + 2 } $name"

 4 Hamadryas
> Q :s :c :b "\r \n { 2 + 2 } $name"

 4 Hamadryas

The :qq adverb is actually the combination of :s :a :h :f :c :b. This interpolates all of the variables, the stuff in braces, and all backslash sequences. If you don’t want to interpolate everything, you can turn off an adverb. This might be easier than specifying several just to leave one out. Put a ! in front of the one to disable. :!c turns off brace interpolation:

qq :!c /No { 2+2 } interpolation/;

Selected quoting forms and adverbs are summarized in Table 4-2 and Table 4-3.

Table 4-2. Selected quoting forms
Short nameLong nameDescription
「…」LiteralDefault delimiter, corner brackets
Q ‘…’LiteralGeneralized quoting with alternate delimiter
Q[…]LiteralGeneralized quoting with paired delimiter
‘…’EscapedDefault delimiter, single quote
q{…}EscapedUse alternate paired delimiter
Q:q […]EscapedGeneralized quoting with :q adverb
“…”InterpolatedDefault delimiter, double quote
qq[…]InterpolatedUse alternate paired delimiter
Q:qq ‘…’InterpolatedGeneralized quoting with :qq adverb
Q:c ‘…{ }…’InterpolatedGeneralized quoting only interpolating closures
Q:to(HERE)LiteralHere doc
q:to(HERE)EscapedHere doc
qq:to(HERE)InterpolatedHere doc
Table 4-3. Selected quoting adverbs
Short nameLong nameDescription
:x:execExecute shell command and return results
:q:singleInterpolate \\, \qq[…], and an escaped delimiter
:qq:doubleInterpolate with :s, :a, :h, :f, :c, :b
:s:scalarInterpolate $ variables
:a:arrayInterpolate @ variables
:h:hashInterpolate % variables
:f:functionInterpolate & calls
:c:closureInterpolate code in {…}
:b:backslashInterpolate \n, \t, and others
:to:heredocParse result as here doc terminator
:v:valConvert to allomorph if possible

Summary

The quoting slang offers several ways to represent and combine text, so you can get exactly what you need in an easy fashion. Once you have the text, you have many options for looking inside the Str to find or extract parts of it. This is still early in the book, though. You’ll see more features along the way and then really have fun in Chapter 15.

Get Learning Perl 6 now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.