keiusui has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I usually use the following code to print paragraphs, and it works just fine:
print <<OUTPUT; Today is Monday, my favorite day of the week. It is my favorite day b +ecause Jerry said "Monday is the best day of the week". Tuesday is m +y second-favorite day. Why can't all days be as great as Monday? Wh +o knows. OUTPUT
However, let's say I want to print out code from within an if statement:
if($today eq 'Monday') { print <<OUTPUT; Today is Monday, my favorite day of the week. It is my favorite day b +ecause Jerry said "Monday is the best day of the week". Tuesday is m +y second-favorite day. Why can't all days be as great as Monday? Wh +o knows. OUTPUT }
The only issue is that I cannot indent all of the code within the curly brackets because then Perl doesn't see the last OUTPUT.

What would be the best way to print out paragraphs of text in such a way that they could be indented within the code?

Thank you so much for your help.

Replies are listed 'Best First'.
Re: best way to print paragraphs of text
by CountZero (Bishop) on Aug 08, 2009 at 22:02 UTC
    Just quote your text and print it:
    if($today eq 'Monday') { print q(Today is Monday, my favorite day of the week. It is my fa +vorite day because Jerry said "Monday is the best day of the week". +Tuesday is my second-favorite day. Why can't all days be as great as + Monday? Who knows.); }

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Further to CountZero's post:

      A here-doc is, to my way of thinking, intended to deal with multiple lines having embedded newlines. The examples given in the OP use a single, very long line with no newlines. If this is, indeed, the type of string keiusui intends to print, then, as CountZero says, just print it and forget about here-docs.

      If one intends to print a string consisting of several lines (i.e., with embedded newlines) using a here-doc, then you are stuck with an approach such as those outlined by desemondo.

      Then you would want to to it like this.

      print <<OUTPUT if $today eq 'Monday'; Today is Monday, my favorite day of the week. It is my favorite day b +ecause Jerry said "Monday is the best day of the week". Tuesday is m +y second-favorite day. Why can't all days be as great as Monday? Wh +o knows. OUTPUT


      Update: This was ment to be a reply to the OP's question and i didnt read the OP's post fully.

      Information is knowledge.
Re: best way to print paragraphs of text
by desemondo (Hermit) on Aug 08, 2009 at 22:14 UTC
    Hi Keiusui,

    For the example you're provided above, you could probably do as CountZero suggests and just quote the string. However if you really want that formatting to print as you've typed it, you could use a 'theredoc', rather than a heredoc.

    You can do this by placing your code above in a variable, or if you need to interpolate stuff at runtime, use a sub instead.

    my $monday_doc = << 'OUTPUT'; Today is Monday, my favorite day of the week. It is my favorite day b +ecause Jerry said "Monday is the best day of the week". Tuesday is m +y second-favorite day. Why can't all days be as great as Monday? Wh +o knows. OUTPUT if($today eq 'Monday'){ print $monday_doc; }
Re: best way to print paragraphs of text
by Your Mother (Archbishop) on Aug 08, 2009 at 22:18 UTC

    CountZero gave good practical advice and I end up doing the same thing HEREdoc and q{-long stings-} often; usually for other code like SQL or JS. If you are putting a lot of paragraphs into code, however, there is probably a sub-optimal design involved.

    Handling text snippets is a better job for a either a template tree or a DB of some sort. Templates being easier to manage by hand, DBs being the only reasonable way to delegate or open editing to many/non-technical users; git + a template tree would be great if it’s just devs working with it.

    This sort of thing is harder, obviously, than putting text into code but it makes so many things better down the line and it starts to get pretty easy once you've mastered a templating or DB kit.

Re: best way to print paragraphs of text
by ELISHEVA (Prior) on Aug 08, 2009 at 23:33 UTC

    If you want to pretty indent the heredoc contents so that they are indented within the if clause, you can get most of the way there with the following code:

    if (1) { (my $sOutput = <<'OUTPUT') =~ s/^\s+|\n(?!\s+\n)//gm; Today is Monday, my favorite day of the week. It is my favorite day because Jerry said "Monday is the best day of the week". Tuesday is my second-favorite day. Why can't all days be as great as Monday? Who knows. This is a second paragraph. OUTPUT print "$sOutput\n"; }

    which outputs

    Today is Monday, my favorite day of the week.It is my favorite day bec +ause Jerry said "Mondayis the best day of the week". Tuesday is my s +econd-favorite day.Why can't all days be as great as Monday? Who kno +ws. This is a second paragraph.

    You'll still need to keep OUTPUT at the start of the line (unless you chose to use whitespace in your end of here-doc marker as JavaFan suggests below), but at least you can indent the remainder of the text. The regular expression s/^\s+|\n(?!\s+\n)//gm removes leading whitespace on all lines. It merges together all lines that have only 1 newline between them and collapses a run of blank lines into a single newline. If instead you want to keep the line breaks exactly as shown in the heredoc, you can use a slightly different regular expression: s/^[^\S\n]+//gm, which results in the output:

    Today is Monday, my favorite day of the week. It is my favorite day because Jerry said "Monday is the best day of the week". Tuesday is my second-favorite day. Why can't all days be as great as Monday? Who knows. This is a second paragraph.

    For more information and other neat tricks you can do with here-documents, see perlop and search for "here-doc".

    Best, beth

    Update 1: added example that preserves line breaks.

    Update 2: corrected my post with a parenthetical comment refering to JavaFan's post below.

Re: best way to print paragraphs of text
by JavaFan (Canon) on Aug 08, 2009 at 23:34 UTC
    You seem to think that here-doc terminators cannot contain whitespace. You're wrong.
    if ($today eq 'Monday') { print <<" OUTPUT"; Today is Monday. Bla bla bla. ... Who knows. MONDAY }
    works just fine (but the output will have leading spaces).

    Note that in your example, the following works too:

    print <<OUTPUT if $today eq 'Monday'; Today is Monday. Bla bla bla. ... Who knows. OUTPUT
      You seem to think that here-doc terminators cannot contain whitespace. You're wrong. ... but the output will [still] have leading spaces ...
      I vaguely recall a discussion somewhere of a multi-line string quotation mechanism (perhaps a here-doc?) in which indentation whitespace would or could be automatically removed at compile-time by invoking the right syntactic spell. I don't see anything like this in perlop. Am I imagining things? Was or is this something associated with Perl 6?
        That's indeed a perl6 thing. In perl5, you need to remove the white space yourself. I would guess with Devel::Declare it may be possible to do some kind of auto-leading-white-space-removal, but my knowledge of the optree is too limited to know how.
        my $output = <<" OUTPUT"; Today is Monday. Bla bla bla. ... Who knows. MONDAY OUTPUT $output =~ s/^ //gm; print $output; __END__ Today is Monday. Bla bla bla. ... Who knows. MONDAY