Understanding how strings work is important in every programming language, but in Perl they are part of the essence of the language. Especially if you consider that one of the acronyms of Perl is Practical Extraction and Reporting Language and for that you need to use lots of strings.

Strings can be placed either between single quotes ' or double quotes " and they have slightly different behavior.

Single quoted strings

If you put characters between single quotes ', then almost all the characters, except the single-quote itself ', are interpreted as they are written in the code.

my $name = 'Foo';
print 'Hello $name, how are you?\n';

The output will be:

Hello $name, how are you?\n

Double quoted strings

Strings placed between double quotes " provide interpolation (other variables embedded in the string will be replaced by their content), and they also replace the special escape sequences such as \n by a real newline and \t by a real tab.

my $name = 'Foo';
my $time  = "today";
print "Hello $name,\nhow are you $time?\n";

The output will be

Hello Foo,
how are you today?

Note, there is a \n right after the comma in the string and another one at the end of the string.

For simple strings such as 'Foo' and "today" that have no $, @, and \ characters in them, it does not matter how they are quoted.

The next two lines have the exact same result:

$name = 'Foo';
$name = "Foo";

E-mail addresses

As @ also interpolates in double quoted strings, writing e-mail addresses needs a little more attention.

In single quotes @ does not interpolate.

In double quotes this code will generate an error: Global symbol "@bar" requires explicit package name at ... line ... and a warning: Possible unintended interpolation of @bar in string at ... line ...

The latter might be the one that provides the better clue what is really the problem.

use strict;
use warnings;
my $broken_email  = "foo@bar.com";

This code, on the other hand, having the e-mail address in single quotes, will work.

use strict;
use warnings;
my $good_email  = 'foo@bar.com';

What if you need both the interpolation of scalar variables but you want to include at marks @ in the string?

use strict;
use warnings;
my $name = 'foo';
my $good_email  = "$name\@bar.com";

print $good_email; # foo@bar.com

You can always escape the special characters, in this case the at-mark @ by using the so-called escape character which is the back-slash \ character.

Embedding dollar $ sign in double quoted strings

In a similar way if you'd like to include a $ sign in an otherwise double-quoted string you can escape that too:

use strict;
use warnings;
my $name = 'foo';
print "\$name = $name\n";

Will print:

$name = foo

Escaping the escape character

There are rare cases when you'd like to include a back-slash character in a string. If you put a back-slash \ in a double-quoted string, Perl will think you want to escape the next character and do its magic.

Don't worry though. You can tell Perl to stop that by escaping the escape character:

You just put another back-slash in front of it:

use strict;
use warnings;
my $name = 'foo';
print "\\$name\n";

\foo

I know this escaping the escape character is a bit strange, but this is basically how it works in every other language as well.

If you'd like to understand this whole escaping business, try something like this:

print "\\\\n\n\\n\n";

see what does that print:

\\n
\n

and try to explain it to yourself.

Escaping double quotes

We saw that you can put scalar variables in double-quoted strings but you can also escape the $ sign.

We saw how you can use the escape character \ and how you can escape that too.

What if you'd like to print a double quote in a double-quoted string?

This code has a syntax error:

use strict;
use warnings;
my $name = 'foo';
print "The "name" is "$name"\n";

when Perl sees the double-quote just before the word "name" it thinks that was the end of the string and then it complains about the word name being a bareword.

You might have already guessed, we need to escape the embedded " character:

use strict;
use warnings;
my $name = 'foo';
print "The \"name\" is \"$name\"\n";

This will print:

The "name" is "foo"

This works, but it is quite hard to read.

qq, the double-q operator

That's where you can use qq or the double-q operator:

use strict;
use warnings;
my $name = 'foo';
print qq(The "name" is "$name"\n);

For the untrained eyes, the qq() might look like a function call, but it is not. qq is an operator and you'll see in a second what else it can do, but first let me explain this.

We replace the double-quotes " that used to surround the string by the parentheses of the qq operator. This means the double-quotes are not special any more in this string, so we don't need to escape them. That makes the code a lot more readable. I'd even call it beautiful, if I did not fear the wrath of the Python programmers.

But what if you would like to include parentheses in your string?

use strict;
use warnings;
my $name = 'foo';
print qq(The (name) is "$name"\n);

No problem. As long as they are balanced (that is, having the same number of opening (, and closing ) parentheses, and always having the opening parentheses before the corresponding closing parentheses) Perl can understand it.

I know. You'll want to break it now, by putting a closing before the opening:

use strict;
use warnings;
my $name = 'foo';
print qq(The )name( is "$name"\n);

Indeed, Perl will give you a syntax error about "name" being a bareword. Perl can't understand everything, can it?

You could, of course, escape the parentheses in the string\) and \(, but we were down that rabbit hole already. No thank you!

There must be a better way!

Do you remember, I wrote qq is an operator and not a function? So it can do tricks, right?

What if we replaced the parentheses around our string by curly braces? {}:

use strict;
use warnings;
my $name = 'foo';
print qq{The )name( is "$name"\n};

That works and prints the string as we meant:

The )name( is "foo"

(even though I have not idea why would I want to print something like that...)

Then the guy from the second row raises his hand, and asks what if you want both parentheses and curly braces in your string, and you want them imbalanced?

You mean like this, right?

use strict;
use warnings;
my $name = 'foo';
print qq[The )name} is "$name"\n];

printing this:

The )name} is "foo"

... there must be a use for the square brackets too, right?

q, the single-q operator

Similar to qq there is also an operator called q. That too allows you select the delimiters of your string, but it works as a single quote ' works: It does NOT interpolate variables.

use strict;
use warnings;
print q[The )name} is "$name"\n];

prints:

The )name} is "$name"\n