FAQ 4.38 Why don't my <<HERE documents work?

Discussion in 'Perl Misc' started by PerlFAQ Server, Apr 18, 2011.

  1. This is an excerpt from the latest version perlfaq4.pod, which
    comes with the standard Perl distribution. These postings aim to
    reduce the number of repeated questions as well as allow the community
    to review and update the answers. The latest version of the complete
    perlfaq is at http://faq.perl.org .

    --------------------------------------------------------------------

    4.38: Why don't my <<HERE documents work?

    Check for these three things:

    There must be no space after the << part.
    There (probably) should be a semicolon at the end.
    You can't (easily) have any space in front of the tag.

    If you want to indent the text in the here document, you can do this:

    # all in one
    ($VAR = <<HERE_TARGET) =~ s/^\s+//gm;
    your text
    goes here
    HERE_TARGET

    But the HERE_TARGET must still be flush against the margin. If you want
    that indented also, you'll have to quote in the indentation.

    ($quote = <<' FINIS') =~ s/^\s+//gm;
    ...we will have peace, when you and all your works have
    perished--and the works of your dark master to whom you
    would deliver us. You are a liar, Saruman, and a corrupter
    of men's hearts. --Theoden in /usr/src/perl/taint.c
    FINIS
    $quote =~ s/\s+--/\n--/;

    A nice general-purpose fixer-upper function for indented here documents
    follows. It expects to be called with a here document as its argument.
    It looks to see whether each line begins with a common substring, and if
    so, strips that substring off. Otherwise, it takes the amount of leading
    whitespace found on the first line and removes that much off each
    subsequent line.

    sub fix {
    local $_ = shift;
    my ($white, $leader); # common whitespace and common leading string
    if (/^\s*(?:([^\w\s]+)(\s*).*\n)(?:\s*\g1\g2?.*\n)+$/) {
    ($white, $leader) = ($2, quotemeta($1));
    } else {
    ($white, $leader) = (/^(\s+)/, '');
    }
    s/^\s*?$leader(?:$white)?//gm;
    return $_;
    }

    This works with leading special strings, dynamically determined:

    $remember_the_main = fix<<' MAIN_INTERPRETER_LOOP';
    @@@ int
    @@@ runops() {
    @@@ SAVEI32(runlevel);
    @@@ runlevel++;
    @@@ while ( op = (*op->op_ppaddr)() );
    @@@ TAINT_NOT;
    @@@ return 0;
    @@@ }
    MAIN_INTERPRETER_LOOP

    Or with a fixed amount of leading whitespace, with remaining indentation
    correctly preserved:

    $poem = fix<<EVER_ON_AND_ON;
    Now far ahead the Road has gone,
    And I must follow, if I can,
    Pursuing it with eager feet,
    Until it joins some larger way
    Where many paths and errands meet.
    And whither then? I cannot say.
    --Bilbo in /usr/src/perl/pp_ctl.c
    EVER_ON_AND_ON



    --------------------------------------------------------------------

    The perlfaq-workers, a group of volunteers, maintain the perlfaq. They
    are not necessarily experts in every domain where Perl might show up,
    so please include as much information as possible and relevant in any
    corrections. The perlfaq-workers also don't have access to every
    operating system or platform, so please include relevant details for
    corrections to examples that do not work on particular platforms.
    Working code is greatly appreciated.

    If you'd like to help maintain the perlfaq, see the details in
    perlfaq.pod.
     
    PerlFAQ Server, Apr 18, 2011
    #1
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.