Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Quote and Quote-like Operators

by Xiong (Hermit)
on Dec 15, 2011 at 10:10 UTC ( #943683=perlmeditation: print w/ replies, xml ) Need Help??

perlop contains a rather lengthy section, Quote and Quote-like Operators, containing a detailed explanation of these related constructs. You may wish to review Regexp Quote-Like Operators, Quote-Like Operators, and Gory details of parsing quoted constructs, all in the same document. This node contains an extremely brief summary, with examples.

In the listings that follow, #: indicates the output of the preceding code.

Quoting String Literals

In the most common case, we wish to store or print a simple string literal as is. The single quotes merely limit the string:

say 'Cwm fjordbank glyphs vext quiz.'; #:Cwm fjordbank glyphs vext quiz.

This works well enough except when the literal string must contain, literally, the single-quote character itself. Then we may escape the troublesome characters or use generic quotes:

say 'a\'b\'c'; #:a'b'c say q|a'b'c|; #:a'b'c

If we need just a literal backslash then we need to escape it, too; otherwise perl will think we're trying to escape the trailing delimiter:

say '\a'; #:\a say '\\'; #:\ say q|\a|; #:\a say q|\\|; #:\

It's irrelevant which delimiters we use in a generic quoting construct except that, obviously, we're better off choosing delimiters that aren't in our string. Other than that, it's a matter of style. Different programmers prefer different delimiters:

say q|a'b'c|; # || say q(a'b'c); # () say q[a'b'c]; # [] say q<a'b'c>; # <> say q/a'b'c/; # // say q*a'b'c*; # ** #:a'b'c

Sometimes we just use generic quotes for clarity, even when plain single quotes would work as well:

say ''; # empty string? say q||; # clearer say ' '; # single space? say q| |; # clearer

Interpolation

Sometimes we want to mix in variable values or escape sequences; then we use interpolation. The double quotes are the most common:

my $foo = 'bar'; say "a-$foo-b"; #:a-bar-b

The previous issues come up with interpolating quotes, too; if we want to include a double-quote character, literally, we need to use generic interpolating quotes:

say qq|This\t('"')\tis a double-quote.|; #:This ('"') is a double-quote.

And again, we can use any delimiters we like.

Common escape sequences

\t tab \n newline \r carriage return \b backspace say qq|a-\t-b-\n-c|; #:a- -b- #:-c

Many, many other escape sequences are possible; see perlop.

Heredocs

As a last resort, peculiar or long strings can be quoted with a heredoc construct:

say <<'HERE'; say qq|This\t('"')\tis a double-quote.|; # my $string = '\a\s\b'; HERE #:say qq|This\t('"')\tis a double-quote.|; #:# my $string = '\a\s\b'; #:

If you don't single-quote the word 'HERE' in the example above, the heredoc will interpolate, much like double quotes.

Heredocs are ugly and confusing, best avoided... unless there's no better way.

Quoting a List

We may want to create a list of quoted strings, perhaps to store in an array. These statements are equivalent:

my @ary = ( 'Cwm', 'fjordbank', 'glyphs', 'vext', 'quiz' ); my @ary = qw| Cwm fjordbank glyphs vext quiz |;

Again, any delimiters may be used with the quote word operator. But please don't make foolish choices.

Other Quote-like Constructs

Regular expressions may be considered quoting, interpolating constructs. Before any matching is done, the contents of a regex will be expanded much as if it were enclosed in double quotes:

my $regex = 'a|b|c'; my $string = 'xxbxx'; if ( $string =~ /$regex/ ) { say 'TRUE' } else { say 'FALSE' }; #:TRUE

Note that in the example above, $regex was assigned the value obtained by simple single-quoting a literal a|b|c. It's also possible to use two other constructs, quote regex and quotemeta:

my $regex = qr/a|b|c/; my $string = 'xxbxx'; if ( $string =~ /$regex/ ) { say 'TRUE' } else { say 'FALSE' }; #:TRUE

Benefits to using qr// instead of q// or qq// include compile-time checking and possible optimization.

Using quotemeta on a string escapes the characters that might be special:

my $regex = '\s'; my $string = '\a\s\b'; if ( $string =~ /$regex/ ) { say 'TRUE' } else { say 'FALSE' }; #:FALSE $regex = quotemeta $regex; if ( $string =~ /$regex/ ) { say 'TRUE' } else { say 'FALSE' }; #:TRUE

Please see also perlreref, perlretut, perlre, perlrequick.

If you've used backticks to do a system call, you might like to know that there is also a generic backtick operator:

say `date`; say qx|date|; #:Thu Dec 15 01:19:30 PST 2011

Summary

  • Use single quotes to specify a literal string.
  • Use double quotes when you want to interpolate a variable or escape sequence.
  • Use generic quotes when you want to avoid ecaping literal quote characters.
  • Use generic quotes to add clarity in some cases.
  • Use any delimiter in generic quotes... but don't go crazy.
  • It's usually best to stick with () [] {} <> // || ** and avoid confusing letter or digit delimiters.
  • Use qw// to build lists of quoted strings.
  • Use qr// to pre-compose regex patterns.
  • Use qx// to avoid tricky backtick quoting issues.

Thanks

  • davido for pointing out some benefits to qr//.
  • ambrus for pointing out some esoteric benefits to qr//.
  • setebos for making clear the need.

Changes

Suggestions for improvements are welcome and will be incorporated.

2011-12-15:
  • new

Comment on Quote and Quote-like Operators
Select or Download Code
Re: Quote and Quote-like Operators
by Anonymous Monk on Dec 15, 2011 at 11:51 UTC

    FWIW, heredocs aren't ugly :) if text is more than one line, heredocs are my first choice, of the form

    my $html = <<'__HTML__'; __HTML__ my $xml = <<'__XML__'; __XML__ my $foo = <<'__EOF__'; __EOF__

    I've often pasted multiline text and had to adjust the delimiters, ditching '' and "" and {} for q~~. With heredocs this is very rare. I've had HERE or EOF show up a few times, but virtually never __EOF__, which I also like for its similarity to __DATA__ and __END__

    Its part of my template, I even have a hotkey in my editor for heredocs

    I also prefer  qw' l i s t ' or  qw/ l i s t/ because no shift key is involved, and its all pinky action (on QWERTY keyboard),  use CGI 3.55 qw/ param /;  use Data::Dump qw' dd ';

    for oneliner portability, i prefer qq// and q//, much easier to move between shells , only have to change leading/trailing "" into '' and vice versa

    For match/substitution, i prefer  s/// and then to avoid leaning toothpick syndrome i switch to one of  s;;;  s=== depending on the regex, similarly because shift isn't required, and its all pinky action :)

    for larger regex I always use balanced  s{}{}ex; or

    s{ }{ }ex;

    though the options are ridiculous :D

    perl -MO=Deparse -e " s///g " perl -MO=Deparse -e " s\\\g " perl -MO=Deparse -e " s[][]g " perl -MO=Deparse -e " s()()g " perl -MO=Deparse -e " s{}{}g " perl -MO=Deparse -e " s!!!g " perl -MO=Deparse -e " s###g " perl -MO=Deparse -e " s vvvg " perl -MO=Deparse -e " s ___g " perl -MO=Deparse -e " s {}//g " perl -MO=Deparse -e " s {}\\g " perl -MO=Deparse -e " s {}vvg " perl -MO=Deparse -e " s {}()g " perl -MO=Deparse -e " s {}[]g " perl -MO=Deparse -e " s {}<>g " perl -MO=Deparse -e " s<><>g "

    you're correct, you definitely want to avoid alphanumeric for delimiters, esp fancy unicode

      FWIW, heredocs aren't ugly :)

      Not on their own perhaps but they do add ugliness to indented code.

      --
      John.

        One can include spaces in the terminating string:
        sub foo { xsh <<' end ;' open 1.xml ; delete //@id ; save :b ; end ; }
        :-)
Re: Quote and Quote-like Operators
by tobyink (Abbot) on Dec 16, 2011 at 08:48 UTC

    I agree with the other comment that heredocs are not ugly, and are often the best way of including multi-line strings in your code (such as big chunks of SQL).

    It might be worth mentioning how heredocs can be stacked:

    use Test::More; use Example::HTML::Reformatter qw/reformat/; is(reformat(<<'IN'), <<'OUT', 'HTML was reformatted'); <html><head ><title>Foo</title><body></html> IN <html> <head> <title>Foo</title> </head> <body> </body> </html> OUT done_testing(1);

    Another thing worth mentioning might be how when bracketting characters are used to quote strings, they must balance.

    my $str = q{Foo{the following curly does not end the quote}but the nex +t one does};

      I'm sorry; I don't understand your heredoc-stacking example. Would you be able to offer a use case compelling to the Perl newcomer?

      Let's refrain from discussing nesting delimiters in generic quotes; I'm not sure I'd want to encourage it. To the newcomer, I'd rather emphasize the value of choosing delimiters wisely.

      Full details are always available in perlop. I'd hoped to avoid mentioning usage such as q][] in a basic introduction. Thank you for your comments.

      Feste: Misprison in the highest degree. Lady, cucullus non facit monachum. That's as much to say as, I wear not motley in my brain....

        I thought the example I provided, where you want to pipe some multi-line input data through a function, and compare the result to an expected set of multi-line output data, is a fairly realistic example of where stacking heredocs might be used. I won't claim to use stacked heredocs on a frequent basis, but I have used them from time to time, and have seen them used by others.

        I use it in this test file for example:

        http://api.metacpan.org/source/TOBYINK/XML-LibXML-PrettyPrint-0.002/t/03indent.t
      If they would be stacked, the first terminator would be OUT, and the latter IN, as a stack is "first in, last out". In this example, there isn't anything magic going on, there are just two of them. No "stacking" involved.
        The word "stack" is used in <<EOF.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://943683]
Approved by moritz
Front-paged by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2014-12-27 10:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (177 votes), past polls