CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in
Add ListingModify ListingTell A FriendLink to TPASubscribeNew ListingsCool ListingsTop RatedRandom Link
Newest Reviews
  • review
  • hagen software
  • NOT GPL!
  • Hagan Software
  • Wasted Time with ...
  • poor pre-sale sup...
  • no response
  • rating the offer
  • Good Stuff
  • Good idea but use...


  •  
    Perl Archive : TLC : Programming : Perl : Quoting Operators and Interpolation
    Guide Search entire directory 
     

    Date Published: 2000-03-01

    If you're sick and tired of backslashing double quote signs, and you want to know why you can't print "japhy@pobox.com" without Perl yelling at you, this article will clear things up for you. We'll straighten out the uses of Perl's varying quoting operators, and learn about interpolation.

    Quoting Operators and Interpolation


    Quoting Contexts

    Perl gives you two quoting contexts, and from these two, there are minor variations. The two parent contexts are single-quoted context and double-quoted context. In single-quoted context, there is no interpolation done at all. In double-quoted context, scalar variables (and array elements and hash values) and arrays (and array slices and hash slices) are interpolated. The term interpolation means that Perl will "expand" or "evaluate" an expression. In single-quoted context, the following string is exactly what you see:

    He said "You owe $10.00 for Joe's, too!" to soldier m\\\n12-@N-6-%foo.

    In double quoted context, the variable $10 would be evaluated (this would be the tenth remembered submatch of a previously matched regular expression, the sequence \\ indicates a literal backslash, the sequence \n indicates a newline character, and the variable @N would be evaluated. In double-quoted context, interpolated arrays expand to a string of their elements, separated by the value of the $" variable.


    Single-Quoted Context

    However, there is only a single way to get this true single-quoted context, and that is with here-docs to be described later. When using single quotes, the backslash (\) comes into play, and there are two places where minor interpolation comes into play; these are to backslash the character being used for quoting, and the other is to backslash the backslash itself, so that if you want a literal backslash as te last character in a quoted string, you can do that:

    $str = '\n is a literal \ and a n'; $str = 'here is a quote \' <--'; $str = 'this ends in a slash\\'; $str = 'a slash and a quote\\\'';

    Perl sympathizes with the plight of the frequency of the apostrophe (single quote) in many languages, and acknowledges that you might really want to put apostrophes in a single-quoted string. So Perl offers the q() operator -- not function, operator. q() takes any set of delimiters (some of which pair as left and right), and treats the string as a single-quoted string:

    $str = q(Don't do that!); $str = q/I said, "You're in for it!"/; $str = q{ for (1 .. 10) { print "$_\n"; } }; $str = q~% cd \~jeffp/pub_html/~;

    You should notice something important from these examples: with paired delimiters {...}, you can nest the delimiters -- meaning, Perl will allow for balanced pairs of these left and right delimiters. These can be the pairs (), [], {}, and <>. If there will be be an uneven number of these paired delimiters (example shown below), the offending delimiter characters must be backslashed.

    $str = q{ print "\{ is hitchcock's profile" }; $str = q<Is it true that 5 \> 2?>;

    The caveat of backslashes and directory paths (under Win32 systems) is mentioned later.

    Perl offers another operator, qw(), which works in a way very similar to split(' ', q()). That is, it takes the expression you give it, treats it like a single-quoted string (q() rules of interpolation are honored) and then uses a special case of the split() function on the string. split(' ') means that leading and trailing whitespace is discarded, and then the resulting string is split on chunks of whitespace. It is the same as the following, but what follows is more complicated than the simple use of split(' '):

    split /\s+/, ($string =~ /(\S.*\S)/s)[0];

    Important note: split(' ') is NOT the same as split(/ /). The former exists as a special case (and can be written as split(" ") as well), while the latter splits a string on the regex of a single space.


    Double-Quoted Context

    In double-quoted context, certain Perl expressions (any scalar value or slice of an array or hash) is expanded to its value, and specific sequences (noted by a beginning backslash) are expanded to their value. Here is a table of these sequences:

    SequenceValue
    \ttab
    \nnewline
    \rreturn
    \fform feed
    \bbackspace
    \aalarm (bell)
    \eescape
    \NNNoctal char (N is octal digit)
    \xNNhex char (N is hex digit)
    \cNcontrol-char
    \$literal $
    \@literal @
    \llowercase next char
    \uuppercase next char
    \Llowercase until \E
    \Uuppercase until \E
    \Qbackslash regex metachars until \E
    \Eend case (or \Q) modification

    For double-quoted context, Perl offers regular double quotes (""), or the qq() operator -- not function, operator. It has the same delimiter rules as q() does; specifically, if you use pairing delimiters, you can nest them, and that other delimiters need to be backslashed if they are to occur in the string as the literal character, and that in a sequence of two adjacent backslashes, a literal backslash is produced:

    $str = qq(Once (upon (a (time) ) ) I used Lisp.); $str = qq/Bad way to print a directory: \/usr\/local\/bin\//; $str = "Hi, $name. Your friends are @friends.\n"; $str = qq,\\\ is a backslash followed by a space,; $str = qq(That'll be \$10.00 :\));

    Another quoting construct that uses double-quoted context are backticks, `...`, available also through use of the qx() operator. The backticks execute their contents as a system command, and return what the command sent to standard output. In scalar context, multiline output is stored in a scalar, each line ending in a newline character; in list context, the output is stored one line per list element, with each element ending with a newline. This quoting construct uses double-quoted interpolation, so you can send Perl variables to a command and they will be interpolated to their values beforehand.

    chomp($username = `whoami`); # ugly, use getpwnam($<) @{ $procs{$username} } = qx/ps -fu $username/; @output = qx!adduser $name!; chomp(@who = qx(finger \@hostname.org));


    Here-docs

    Earlier, I said there was only one way to get true single-quoted context, where what you type is what you get. That way is using here-docs, which is a quoting construct borrowed from shell scripting.

    The simplest form of a here-doc is as follows. Note there is no space between the << and the here-doc label. The label must appear exactly as written at the end of a here-doc, and must be followed by a newline.

    <<LABEL text here is double-quoted context LABEL

    Here-docs are simply another form of quoting text, so all rules about commas and semicolons apply. The most common use of a here-doc is to print a block of text at once:

    print <<END_HTML; # note the semicolon <html> <head> <title>...</title> </head> <body>...</body> </html> END_HTML some_other_code();

    If you leave the semicolon out, then Perl will see your code as

    print <<END_HTML some_other_code();

    which is probably not what you intended. Because here-docs are just another quoting mechanism, you can use them anywhere you would use a regular string:

    $quote = <<QUOTE; Now is the winter of our discontent! QUOTE print <<END_A, "\n---\n\n", <<END_B; $$ [$username] END_A $data{request} (on $data{date}) END_B

    Here-docs, by default, are double-quotish. However, you can specify the quoting context by placing quotes around the identifier:

    # when quotes are used, there can # be a space after the << $literal = << 'EVERYTHING'; Two slashes: \\ A slash an a dollar sign: \$ EVERYTHING does not end yet EVERYTHING $dquote = << " double quotes"; Hello, $name. Perl version $] double quotes (not over yet, need three leading space...) double quotes

    The end of a here-doc is when the identifier is found alone on a line, appearing exactly as it did at the beginning of the here-doc (minus any quotes), and followed by a newline. Any leading space before the identifier must be represented at the end of the here-doc as well, as shown by the previous example.


    Caveats

    Along with quoting and interpolation come many common errors. I'll try to right these wrongs.


    Windows

    Windows and Perl are smart: directory paths can have forward slashes. If you insist on using backslashes, do so carefully:

    # in double quotes, double the backslash $path = "c:\\windows\\desktop\\file.txt"; # in single quotes, you can double them $path = 'c:\\windows\\desktop\\file.txt'; # or not: $path = 'c:\windows\desktop\file.txt';

    If you don't double your backslashes in double-quoted context, you'll end up with some funny filenames:

    # \t is a tab, \a is a *ding!* $file = "c:\telnet\app.log";

    Beware of trailing backslashes, which might cause a syntax error:

    # oops, backslashed the ' $path = 'c:\windows\desktop\';

    In general, variables holding directories are better off without trailing slashes. It allows for nicer looking code:

    $dir = "c:/windows/desktop/"; $file = $dir . "file.txt"; $file = "${dir}file.txt"; $file = "$dirfile.txt"; # <-- oops!

    In that last line, Perl expected to find a $dirfile variable. If you leave the trailing slash off a directory path, you can write something much more visually appealing, like "$dir/file.txt".


    Arrays in Quotes

    Rarely do you want to place arrays inside quotes, if the array holds the contents of a file:

    open FILE, "file" or die "can't open file: $!"; @lines = <FILE>; close FILE; print "@lines";

    Now, aside from that being a terribly inefficient way to print the contents of a file, it also "mysteriously" places a space in front of every line but the first, due to the interpolation of an array in double-quoted context.

    And if you are printing an email address in double-quoted context, Perl asks that you backslash the @ sign, because otherwise, it'll try printing the contents of the array it sees, and if that array doesn't exist, it'll give you a warning:

    print "Email me at japhy@pobox.com.\n";

    elicits:

    In string, @pobox now must be written as \@pobox at ...


    References

    The $DIGIT variables ($1, $2, etc.) are set by parenthesized subpatterns inside regular expressions. The $" variable, which defaults to a space, is inserted between each element of an array (or array slice or hash slice) in double-quoted context. If you're using English.pm, its alternative name is $LIST_SEPARATOR. These are all documented in the perlvar section of the Perl man pages.

    Here-docs are discussed in the perldata section of the Perl man pages. If you're really interested in knowing the strict syntax of forming here-docs, I've written documentation in Backus-Naur Form (a set of grammar rules for specifying language elements), available at my Perl web site. That document will work its way into a documentation patch, to be seen in the docs for Perl 5.6 (if all goes well).  

    Jeff "japhy" Pinyan has 2.5 years of Perl, inc., written 3 CPAN modules and wrote for TPJ article. He is currently is currently writing a Perl book entitled "The Art of Perl: Elegant Perl Style".

     
     


    About The Perl ArchiveLink Validation ProcessSearch Tips
    Web Applications & Managed Hosting Powered by Gossamer Threads
    Visit our Mailing List Archives