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 Str
s; 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 Str
s are escaped strings. The single tick
acts as the delimiter for these Str
s. 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
Str
s 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 Str
s 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
Str
s. Some people call this “string addition.” The output shows the two Str
s 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 Str
s, but you can also concatenate
more than two Str
s at a time:
put 'Hamadryas ' ~ 'perlicus'; put 'Hamadryas' ~ ' ' ~ 'perlicus';
The join
routine glues together Str
s with the first Str
you give it:
my $butterfly-name = join ' ', 'Hamadryas', 'perlicus'
You can make larger Str
s 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ņš' 'πεταλούδα' 'भंबीरा' 'פרפר'
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 Str
s character by character.
The numbers comparison operators are symbols, but the Str
s use operators made up of letters.
The eq
operator tests if the Str
s 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 Str
s. 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 Str
s 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 Str
s 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 Str
s 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 Str
s will also make easier some of the
code you’ve already seen.
Interpolated Str
s 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 Str
s:
my $answer = prompt( 'What\'s your favorite animal? ' ); put "\$answer is type {$answer.^name}"; put "You chose $answer";
Like with the previous Str
s, you can choose a different
delimiter for interpolated Str
s. 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.
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 Str
s. 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 Str
s 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 Str
s:
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.
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.