Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

quotes in Perl

by apotheon (Deacon)
on Oct 20, 2004 at 22:33 UTC ( [id://401006]=perltutorial: print w/replies, xml ) Need Help??

Quotation marks are fairly ubiquitous in Perl, as in most programming languages. Different methods of quoting exist, and each has different uses and a different set of behaviors associated with it.

This document is intended as a treatment of the subject of delimiting strings — "quoting". I try to keep it from devolving into lengthy digressions on tangential topics, such as escape characters and interpolation. Such topics do tie in with the use of such delimiters, however, and must to some degree be addressed. Further information can be found at perlop.


single-quotes

Single quotation marks are used to enclose data you want taken literally. Just as the <code></code> tags here at the Monastery make all text they enclose literally rendered, whitespace and all, so too does a set of single-quotes in Perl ensure that what they enclose is used literally:
#!/usr/bin/perl -w use strict; my $foo; my $bar; $foo = 7; $bar = 'it is worth $foo'; print $bar;

This example, when run, produces the following:
it is worth $foo



double-quotes

Double quotation marks are used to enclose data that needs to be interpolated before processing. That means that escaped characters and variables aren't simply literally inserted into later operations, but are evaluated on the spot. Escape characters can be used to insert newlines, tabs, and other special characters into a string, for instance. The values, or contents, of variables are used in double-quoted strings, rather than the names of variables. For instance:
#!/usr/bin/perl -w use strict; my $foo; my $bar; $foo = 7; $bar = "it is worth $foo"; print $bar;

This example, when run, produces the following:
it is worth 7

Double-quotes interpolate scalar and array variables, but not hashes. On the other hand, you can use double-quotes to interpolate slices of both arrays and hashes.


escape characters

The interpolating effects of double-quotes creates a necessity of using escaped characters to reproduce characters within a string that would be displayed literally within single-quotes, however. For instance, to add quotes to the above-printed string in the double-quote example, you would have to do something like this:
#!/usr/bin/perl -w use strict; my $foo; my $bar; $foo = 7; $bar = "it is \"worth\" $foo"; print $bar;

The backslash "escapes" the quotation mark that follows it, so that running the above produces the following:
it is "worth" 7

An exception to the literal interpretation behavior in the use of single-quotes is when you wish to include single-quotes inside the string. In that case, you must escape the single-quotes you want inside the string so the Perl compiler can discriminate between them and the single-quotes that delimit the string:
#!/usr/bin/perl -w use strict; my $foo; my $bar; $foo = 7; $bar = 'it is \'worth\' $foo'; print $bar;

This example, when run, produces the following:
it is 'worth' $foo

In any interpolating quotation scheme, such as double-quotes (or qq and interpolating uses of <<, as described below), @ and $ characters must be escaped when you want them used literally. If they are not, they will be treated by the Perl compiler as indicators of variable names.


quoting without quotes

In Perl, you can use methods other than quotation marks to "quote" a string. This functionality makes using strings that contain quotation marks much easier sometimes, because those quotation marks no longer need to be escaped. There are three simple methods of doing this with the letter q.

In the following three sections, on the subjects of q, qq, and qw notation, I refer exclusively to the use of parentheses as delimiters. Other delimiters can be used, however, which allows you to avoid having to escape the characters you choose to use as delimiters if you must also include instances of them in your string. For instance, instead of using parentheses, you could also use brackets ( [ ] ), braces ( { } ), asterisks ( * * ), and (almost?) any other non-whitespace characters. It's worth noting that in the case of an alphanumeric character there must be a space between the q (or qw, or qq) and the character in question.


q

The first way to quote without quotes is to use q() notation. Instead of using quotation marks, you would use parentheses with a q preceding them:
#!/usr/bin/perl -w use strict; my $foo; my $bar; $foo = 7; $bar = q(it is 'worth' $foo); print $bar;

This example, when run, produces the following:
it is 'worth' $foo

The q() function works the same as single-quoting your string, with the exception that you no longer need to escape single-quotes that appear within the string. You would, however, have to escape any parentheses you need in the string.


qq

In the same way that double-quotes add interpolation to the functionality of single-quotes, doubling the q adds interpolation to quoting without quotation marks. For instance, if you wanted to avoid escape characters and interpolate $foo in the above code, and wanted to use double-quotes around the word worth, you might write this:
#!/usr/bin/perl -w use strict; my $foo; my $bar; $foo = 7; $bar = qq(it is "worth" $foo); print $bar;

This example, when run, produces the following:
it is "worth" 7



qw

You can use qw to quote individual words without interpolation. Use whitespace to separate terms you would otherwise have to separate by quoting individually and adding commas. This is often quite useful when assigning lists to array variables. The two following statements are equivalent:
@baz = ('one', 'two', 'three'); @baz = qw(one two three);



here documents

If you want to quote many lines of text literally, you can use "Here Document" notation. This consists of an introductory line which has two less-than signs (aka "angles" or "angle brackets": << ) followed by a keyword — the end tag — for signalling the end of the quote. All text and lines following the introductory line are quoted. The quote ends when the end tag is found, by itself, on a line. For example, if the end tag is EOT:
#!/usr/bin/perl -w use strict; my $foo = 123.45; my $bar = "Martha Stewedprune"; print <<"EOT"; ===== This is an example of text taken literally except that variables are expanded where their variable names appear. foo: $foo bar: $bar EOT

This example, when run, produces the following:
===== This is an example of text taken literally except that variables are expanded where their variable names appear. foo: 123.45 bar: Martha Stewedprune

The type of quotation marks placed around the end tag is important. For instance, in the above example, EOT is double-quoted, and as a result the values of $foo and $bar are substituted for the variable names. Double-quoting the end tag causes the quoted block of text to be interpolated as it would be with double-quotes. Use of single-quotes would cause it to be used literally, without interpolation, as though the quoted block of text were delimited by single-quotes rather than being referenced as a "here document". Omitting the quotation marks entirely defaults to behavior the same as using double-quotes.

some notes to keep in mind:
  • The end tag specifier must follow the << without any intermediate space.
  • The actual end tag must be exactly the same as specified in the introduction line.
  • The introduction line must end with a semicolon.
The use of here documents is particularly useful in Perl scripts that include HTML and other markup, because it allows you to keep the markup relatively free of escape characters that would otherwise reduce the readability of it.


Thanks due the PerlMonks community members who contributed suggestions and comments in discussion below.

- apotheon
CopyWrite Chad Perrin

Replies are listed 'Best First'.
Re: quotes in Perl
by perlcapt (Pilgrim) on Oct 20, 2004 at 22:49 UTC
    I would add the here-is quoting i.e.<<"endtag" and the significant difference of the different versions of quoting the end-tag.

    Other than that, it seems very clean and the examples are good. -ben

      Unfortunately, as a relative newbie to Perl, I don't know enough about here-is quoting to be able to write that section myself at this time. It's something I'll have to look into, and get back to later.

      Thanks for the comment.

      - apotheon
      CopyWrite Chad Perrin

        Here Documents

        If you want to quote many lines of text literally, you use the "Here Document" notation which consists of an introductory line which has two open angles followed by a keyword, the end tag, for signalling the end of the quote. All text and lines following the introductory line are quoted. The quote ends when the end tag is found, by itself, on a line. For example, the end tag is "EOT":
        <font size="-1">#!/usr/bin/perl -w use strict; my $foo = 123.45; my $bar = "Martha Stewedprune"; print <<"EOT"; ===== This is an example of text taken literally except that variables are expanded where their variable names appear. foo: $foo bar: $bar EOT
        This example, when run, produces the following:
        ===== This is an example of text taken literally except that variables are expanded where their variable names appear. foo: 123.45 bar: Martha Stewedprune

        They way you quote, the end tag is important: like their regular quote counterparts, double-quotes allow expansion of variables and special characters, single quotes don't allow expansion. You may also have a bare, unquoted, end tag; this is equivalent to a double quote, i.e., expansion expansion.

        Some warnings:

        • The end tag specifier must follow the << without any intermediate space.
        • The actual end tag must be exactly the same as in the introduction line.
        • Don't forget that the introduction line must end with a semicolon, just like any other perl statement.
        The here document is particularly useful when embedding HTML in Perl because it increases the readability of the HTML. The quote character is printed out without any escapes. For example:
        my $url = "http://www.maperl.com"; my $text = "Mother of Perl"; print <<"EOT"; <a href="$url">$text</a> EOT
        Prints just what we would hope:
        <a href="http://www.maperl.com">Mother of Perl</a>

Re: quotes in Perl
by TheEnigma (Pilgrim) on Oct 20, 2004 at 23:10 UTC
    Well done!

    You might want to add, however, that with q, qq, and qw, delimiters other than parentheses can be used. [] and {} will work, as will just about any punctuation mark, I believe. Then, to use your delimiter within the quoted string, the rule would be: escape whatever your delimiter is.

    TheEnigma

      just about any punctuation mark

      Actually, you can use almost any character, not just punctuation. The only thing is, with alpha delimiters, you need a space between the operator and the delimiter. This can be used for all manner of nefarious purposes. Quick example:

      $_ = qq qHelloq; s sHss; print y yyyc;
      I knew I'd forget something. Thanks for the reminder. I'll get right on that.

      - apotheon
      CopyWrite Chad Perrin
Re: quotes in Perl
by ikegami (Patriarch) on Oct 21, 2004 at 05:28 UTC

    Unmentioned are:

    • Special sequences such as \n.
    • Which characters need to be escaped in which kind of quotes.
    • What happens if you escape a character that doesn't need escaping.
    • Interpolation of arrays.
    • Non-interpolation of hashes, globs and code.
    • Special variables affecting interpolation, such as $, (and maybe only $,).
    • How to interpolate expressions using "@{[ expr ]}"
    • <<marker vs <<"marker" vs <<'marker'.

    I'm not saying that any of these things should be mentioned, just that you should consider whether they should be mentioned or not.

      Half of the issues you raise here is more about interpolation than about quoting. The document is about quoting, and so IMHO it should keep itself to quote matters. Some aren't directly about quoting, and some aren't directly about interpolation.

      Perhaps one can do a sister document that is about quote interpretation that would include both interpolation issues and and escaping issues, and link between it and this document.

      ihb

      See perltoc if you don't know which perldoc to read!
      Read argumentation in its context!

Re: quotes in Perl
by bobf (Monsignor) on Oct 21, 2004 at 21:10 UTC

    Very nice, concise overview. A couple of additional notes to keep in mind regarding here docs:

    • The end tag specifier must follow the << without any intermediate space.

      If the end tag is quoted explicitly (with either single or double quotes), spaces may be present:
      print << "ENDTAG"; # works print << 'ENDTAG'; # works print << ENDTAG; # syntax error!
    • Any leading spaces in the text of the here doc will be printed as such, which means using here docs in indented blocks gets messy:

      Non-indented code block
      print "printing here doc:\n"; print <<"ENDTAG"; This text has 0 leading spaces This text has 4 leading spaces ENDTAG OUTPUT: printing here doc: This text has 0 leading spaces This text has 4 leading spaces
      Indented code block (same output as above)
      { print "printing here doc:\n"; print <<"ENDTAG"; This text has 0 leading spaces This text has 4 leading spaces ENDTAG }
      But, if the printed text includes leading whitespace, spaces can be included as part of the end tag to clean up the code block:
      { print "printing here doc:\n"; print <<" ENDTAG"; This text has 4 leading spaces ENDTAG } OUTPUT: printing here doc: This text has 4 leading spaces
    • The Filter::Indent::HereDoc and Filter::HereDocIndent modules allow here docs to be used within indented code blocks without adding the leading whitespace from the indentation to the output.
Re: quotes in Perl
by ihb (Deacon) on Oct 21, 2004 at 11:20 UTC

    Well done! This gives a good overview of Perl's quoting constructs. IMHO, it should keep being that -- an overview. The details are documented in perlop and there's no reason to double document it. If perlop isn't clear enough let's make improvements to that document instead. So my real intent of this reply is to request that you start the document by stating what it's for and saying that the details about quoting in Perl in found in perlop.

    This below is just details and I'm not sure whether or not this should be included in this document, but perhaps the text should be adjusted to not contradict them.

    Here-docs can also have backticks around them, and they will then execute the commands in it. I've never seen this used, and since I'm not a fan of `` nor qx() (but like readpipe()) I really don't like <<`CMDS`. It's just sick.

    The second detail is that all chars, except whitespaces, can be delimiters.

    print q xHello World!x;
    prints, as expected (?) "Hello World!". If it's an alphanumeric delimiter a whitespace between it and the q is required.

    You call q() a function. I believe it's more correct to call it an operator.

    As an editorial change I'd prefer to see all Perl bits wrapped in code tags, even a single q if the Perl operator is referenced, but that's very much a matter of taste.

    Again, well done!

    ihb

    See perltoc if you don't know which perldoc to read!
    Read argumentation in its context!

      That's very good advice. Thank you. I've edited as suggested (removing contradictions, et cetera).

      In my defense, the only reason (at least most of) the untagged code items were overlooked when I posted, rather than intentionally remaining untagged, is this: my reference to q as a function was due to misremembering it as being referred to as such by Schwartz and Christiansen in Learning Perl. I now realize they called it "notation" and that it was Castro's PERL and CGI for the World Wide Web that called q a function.

      Again, great advice. Thank you.

      - apotheon
      CopyWrite Chad Perrin
Re: quotes in Perl (opinionated note on coding style)
by dimar (Curate) on Feb 09, 2005 at 18:04 UTC
    The use of here documents is particularly useful ... because it allows you to keep the markup relatively free of escape characters that would otherwise reduce ... readability

    (opinionated note on coding style, your preference may vary)

    The HERE doc syntax was once a favorite here, but now it has been completely abandoned because:

    • 1) There were cases of too many 'escape' chars strewn about, (as mentioned elsewhere in this thread) which motivated a 'zero-tolerance' bias to *absolutely ban all ugly escape sequences*.
    • 2) There were cases where *some* of the variables were intended to be interpolated, but not others (e.g., with code-generation scripts) so it was not clear whether to use "EOT" or 'EOT' (as mentioned elsewhere in this thread).
    • 3) Indentation hassles (as mentioned elsewhere in this thread).

    Because of these issues, we made a stylistic decision not to use HERE doc syntax anymore, and instead use the very flexible quotelike operator with all variables 'concatenated in' instead.

    Thus, your example would become:

    use strict; my $foo = 123.45; my $bar = "Martha Stewedprune"; ### --------------------------- print q^ ===== This is an example of text taken literally except that variables are expanded where their variable names appear. foo: ^.$foo.q^ bar: ^.$bar.q^ (Our *uninterpolated* variable names are "$foo" and "$bar" ... and we didn't need escape chars to tell you that). ^; ### ---------------------------

    All you have to worry about is to make sure your quotelike delim character (caret) is never used in the document. If it is, just change it to something else. Moreover, you can indent this however you want without external module dependencies. Here, we just use comments to make the document visually distinct from the rest of the script.

      Hmm, so instead of ensuring some variables are not interpolated by replacing "$foo" with "\$foo", you instead ensure the other variables are interpolated by replacing "$bar" with "^.$bar.q^".

      That doesn't seem like such a good trade to me.

      Hugo

        It can be a good trade if most of your variables are uninterpolated. In that case you want the unusual form to be the "marked" form, which helps prevent mistakes. That's the justification for Perl 6's version of the same trick, only it's spelled \qq[$bar] there.
Re: quotes in Perl
by japhy (Canon) on Aug 03, 2005 at 16:52 UTC
    In regards to:
    • The end tag specifier must follow the << without any intermediate space.
    • The actual end tag must be exactly the same as specified in the introduction line.
    • The introduction line must end with a semicolon.
    only the middle is correct. The only time the tag specifier must immediately follow the << is when it isn't quoted. That is, << "FOO" is ok whereas << FOO is not. And as for the semicolon, the truth of that matter is that the << "XXX" is merely a placeholder for a quoted string and the rest of the expression its in must continue to flow naturally.

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: quotes in Perl
by nedals (Deacon) on Oct 21, 2004 at 07:02 UTC
    Minor gotcha in the here-is doc
    print <<HTML; .. <style type="text/css"> \@import(url) </style> .. .. HTML
    Don't forget to escape the '@' symbol.

      I don't experience that gotcha with a modern perl.

      However, a nicer fix than too many backslashes strewn in the data would be not to interpolate the Here-doc:
          print <<'HTML';

      Look again at jZed's post or ikegami's last point.

      Cheers, Sören

      You wish to create an HTML doc using <<HTML; that requires interpolation.

      An @import (style sheet) or email address may be included. If the '@' symbol is not escaped, an error message will be returned that refers ONLY to the first line of the here-is

      Global symbol "@import" requires explicit package name at /usr/local/a +pache/..... line 100. Execution of /usr/local/apache/.... aborted due to compilation errors.

      Knowing the above helps to quickly locate the problem. (or avoid it)

      Just a item to add to your
      ...some notes to keep in mind:...
      I don't know what you're referring to, as there's nothing remotely similar to the example code you've indicated in the text of my tutorial. I have added a notation about escaping @ and $ symbols in interpolated strings within the "escape characters" section, however.

      - apotheon
      CopyWrite Chad Perrin
Re: quotes in Perl
by Anonymous Monk on Apr 08, 2009 at 08:44 UTC
    #add quotes @ARGV = (1, 2, 3, 4, 5, 6); @ARGV = map { $_ = '"'.$_.'"' } @ARGV; #add quotes print "@ARGV"; result: "1" "2" "3" "4" "5" "6"
Re: quotes in Perl
by Anonymous Monk on Aug 06, 2012 at 21:00 UTC
    very informative

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perltutorial [id://401006]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-03-19 05:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found