Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Here, doccy doccy. nice doccy. heredoc, treat.

by Vynce (Friar)
on Jun 21, 2001 at 05:56 UTC ( #90272=perlmeditation: print w/replies, xml ) Need Help??

Today in the Chatterbox, maddfisherman had some questions about the heredoc quoting mechanism, and OeufMayo and i started answering him, and brought up some things that tinman didn't know, and that brought up stuff none of us knew, so we ran some test scripts and found some interesting things.

first, some things i did know:

#!/usr/bin/perl -w use strict; my $foo = 'date'; print <<'SINGLE'; $foo SINGLE print <<"DOUBLE"; $foo DOUBLE print <<`BACK`; $foo BACK print <<IMPLIED; $foo IMPLIED
as the experienced heredoc user should know, this prints something like
$foo date Wed Jun 20 15:33:51 PDT 2001 date
Note that with no quotes, double quote interpolation is implied. (note, too, that your date probaby differs from mine.)

but what if you want to use other quoting mechaisms? i wanted to put a big long list into a qw(), and i tried

my @list = <<qw(HERE); Foo Bar Baz HERE
but it can't find string terminator qw.
my @list = qw <<HERE;
can't find string terminator >.
my @list = qw(<< HERE); Foo Bar Baz HERE
did better, but only because i consider the runtime error Can't locate object method "Baz" via package "HERE" at line 23. to be better than not compiling. next step? well, this won't work:
my $bar = <<HERE; Foo Bar Baz HERE my @list = qw($bar);
because the $bar in qw() is not interpolated. this brings up the interesting point of how qw works. further tests seem to indicate that all the quoting functions (q, qq, qr, qw, and qx currently, and i think we get more in perl6) are hard to use with heredocs. in fact, aside from trivial cases, they seem to be hard to use, until you realize that they are operators and not functions. which brings up more questions, like "can we get at the underlying functions?" and "if so, how?" things along those lines.

so, uh, perhaps a heredoc tutorial and a quoters tutorial would be in order.


thanks to maddfisherman, OeufMayo, myocom, and others in the chatterbox for their assistance.

update: fixed some links. and no, CheeseLord i can't think of any specific reason to do it with qw//, but with some of the forthcoming quoting operators, maybe.

update 2: fixed IMPLIED as implied by Particle. bad copying on my part.


Replies are listed 'Best First'.
Re: Here, doccy...*woof*
by footpad (Abbot) on Jun 21, 2001 at 06:28 UTC

    It is written in the POD of perldata (version 5, release 6):

    A line-oriented form of quoting is based on the shell "here-document" syntax. Following a << you specify a string to terminate the quoted material, and all lines following the current line down to the terminating string are the value of the item. The terminating string may be either an identifier (a word), or some quoted text. If quoted, the type of quotes you use determines the treatment of the text, just as in regular quoting. An unquoted identifier works like double quotes. There must be no space between the << and the identifier. (If you put a space it will be treated as a null identifier, which is valid, and matches the first empty line.) The terminating string must appear by itself (unquoted and with no surrounding whitespace) on the terminating line.

    Granted it's a little oblique, but it is there--as someone once reminded me. Since then, I have seen it mentioned in a couple of other places, including (if memory serves) Rat, Camel (currently 50% off, via that link), and the Spikey Ball.


      yes, and from perlop,

      Quote and Quote-like Operators While we usually think of quotes as literal values, in Perl they function as operators, providing various kinds of interpolating and pattern matching capabilities. Perl provides customary quote characters for these behaviors, but also provides a way for you to choose your quote character for any of them.
      nowhere does it imply (to me) that there are situations where you can use " but not qq(), so i would expect to be able to use
      print <<qq~DOUBLE~; $foo DOUBLE
      but i can't.

      and that doesn't explain or demonstrate other weird uses of heredoc syntax, for example,

      my @list = (<<HERE, <<THERE, <<EVERYWHERE); cluck, cluck HERE baa, baa THERE e i e i o EVERYWHERE print "with a ", shift @list, "and a ", shift @list, "singing ", shift + @list;
      so i'd still like a tutorial. but maybe i'll have to write it myself.

      Since then, I have seen it mentioned in a couple of other places, including (if memory serves) Rat, Camel (currently 50% off, via that link), and the Spikey Ball.

      nit: It's not a rat, it's a mouse! Quick quote from the Colophon:

      The animal featured on the cover of CGI Programming for the World Wide Web is a mouse, a rodent of the family Muridae.

      This ends today's extremely pointless fact, g'day!

      Dr. Michael K. Neylon - || "You've left the lens cap of your mind on again, Pinky" - The Brain
Re: Here, doccy doccy. nice doccy. heredoc, treat.
by CheeseLord (Deacon) on Jun 21, 2001 at 06:35 UTC

    A small question, perhaps, but why would you need to use here docs with qw? The following would do what (I think) you're trying to do with your final section of code:

    my @list = qw( Foo Bar Baz ); print "@list\n";

    Will print out Foo Bar Baz unless you have a different list item separator...

    I'm more than willing to concede that I likely am just not thinking hard enough (or I don't know enough) to envision a case where this wouldn't be optimal, but... I just don't see why here-docing things like qw would ever be necessary (or really, even desirable).

    Although I can't deny it is interesting.

    Update: (re: jeffa) Point taken. :)

    Update #2: (re: Vynce) True, there could (should?) be some uses for this sort of thing in the future. I guess I was just thinking in "Why?" instead of "Why not?" mode.

    His Royal Cheeziness

      Not to be a complete smart arse, but TIMTOWTDI. Seriously, there is no rational reason, just the never ending curiosity that drives the CRT radiation thriving people to do weird and insane stuff with Perl. God bless 'em. *sniff*


Re: Here, doccy doccy. nice doccy. heredoc, treat.
by Abigail (Deacon) on Jun 22, 2001 at 04:40 UTC
    Anything that allows for interpolated context (which means qq, qx and qr) can fairly easily be adapted to use here docs:
    print `${\<<HERE}`; date HERE
    print qx {${\<<HERE}}; date HERE
    And for qx:
    print qr /${\<<HERE}/; x*foo HERE
    For q and qq, we already know what to do, single or double quote the delimeter. Which leaves us with qw, which is fairly simple too:
    my @words = split ' ' => <<'HERE'; some words go here HERE

    -- Abigail

Re: Here, doccy doccy. nice doccy. heredoc, treat.
by chipmunk (Parson) on Jun 21, 2001 at 19:24 UTC
    Next you'll be wanting to quote the q() delimiters with qq(): q qq(DELIMITER)Here is my happy string!qq(DELIMITER); Sorry, you just can't do that.

    On the other hand, you could get the effect of qw() with a heredoc like this:

    my @list = split(' ', <<HERE); some whitespace separated words HERE

      actually, a nitpick -- you need your heredoc to be:

      my @list = split(' ', <<'HERE'); some whitespace separated words and possibly $a varaiable or $2 HERE
      note 'HERE' rather than HERE. qw does not interpolate.

      otherise, yes, that solution does work -- for qw(). and i'm sure a similar solution could be made to work for qr//. and of course q(), qq() and qx() are all trivial (though the special case qx'' is not so trivial, as far as i can tell). but perl6 introduces new quoting mechanisms (including, i think, customizable quoting mechanisms), and i might like to be able to use heredocs with those.

      although, i guess i do take your point -- the quotes around the HEREDOC delimiter are not actually being used as those quotes in that case. so maybe heredoc could have an optional second argument (don't ask me how, i'm jsut thinking out loud here) that says what quoting mechanism to use. (ok, nevermind, i'll suggest how after all) like

      print <<(HEREDOC, qx); date df HEREDOC
      (currently, that gives this warning:
      Use of bare << to mean <<"" is deprecated at line 23.
      so we'd not be breaking good existing uses of heredocs.)

Re: Here, doccy doccy. nice doccy. heredoc, treat.
by particle (Vicar) on Jun 22, 2001 at 00:24 UTC
    just one nit to pick... in your example above,
    print <<IMPLIED; $foo IMPLIED;
    you have a semi-colon after the string terminator. this won't compile on my ActiveState Perl build 623, with or without strict and warnings. i've only been using Perl since 5.005_03, so i'm not sure if this is a holdover from earlier versions, or a bug. otherwise, your example is accurate, for *NIX. on Win32 of course, the `date` call waits for user input, and outputs something like
    The current date is: Thu 06/21/2001 Enter the new date: (mm-dd-yy) date
    when enter is pressed. yuck.


      hey, i just noticed something in my output from running 'date' in a heredoc on Win32. look closely at the output:
      The current date is: Thu 06/21/2001 Enter the new date: (mm-dd-yy) date
      when date is run from the command line, the output is:
      The current date is: Thu 06/21/2001 Enter the new date: (mm-dd-yy)
      so why does date (the contents of $foo) appear when run from a heredoc with backtick interpolation? this seems to be more than just a fancy way of quoting. can someone verify this behaviour on *nix?

      curiouser and curiouser...


        well, if you've copy-pasted my version, you'll note that after printing `date`, it prints "date" -- which would make it appear to be right after the backticked version. move the IMPLIED heredoc to before the BACK heredoc aand you should see that change.

        also, my version of date and yours are different; mine doesn't ask for the new date if called with no arguments. sorry for the inconvenience; i hope i didn't make your machine forget the date.


Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://90272]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (6)
As of 2023-02-05 06:34 GMT
Find Nodes?
    Voting Booth?
    I prefer not to run the latest version of Perl because:

    Results (31 votes). Check out past polls.