I much prefer join over sprintf (as well as over here-docs or multi-line quoted strings or concatenation). That preference took a lot of years to form but has now lasted almost as many years. Other techniques don't scale nearly so well, IME, in the face of on-going maintenance and growing size and complexity of the string and programmers' potential for simple mistakes.

In the rare case of using a Perl here-doc as a quick solution, I also move it to be top-level. I also have a somewhat unusual editor configuration that includes showing trailing whitespace (something a significant percentage of my coworkers don't appear to have -- based on them seeming oblivious to the trailing whitespace that they sometimes commit). And even those here-docs rarely last very long.

Heck, even in the short term I'd likely just replace it with a multi-line quoted string:

( my $string= q{ ... } ) =~ s/(?=^|(\n))\n[^\S\n]+/defined $1 ? "\n" : ''/ge;

(Clever undenting regex included just to show how easy it is to eliminate the opening newline that this adds -- not because I find myself actually using such.)

Having here-docs at the top level is also annoying. Not as annoying as not being able to re-indent code w/o breaking it, of course.

SQL seems to be one of the most common examples of the use of a here-doc. I particular dislike using here-docs for SQL. By using join, I don't have to suffer due to SQL not allowing trailing commas, here-docs not supporting comments nor excluding lines conditionally, or lots of other things.

But most SQL I write ends up looking more like:

$db->select( [ "this", "that", "theother", "COUNT(*) as things" ], join( ' ', "foo", "LEFT JOIN bar USING( id )", ), [ "? <= stamp", "stamp < ?", @exclude ? "this NOT IN ( ?? )" : (), ], "GROUP BY this, that, theother", "ORDER BY that, this", "LIMIT $size OFFSET $skip", "HAVING 1 < count(*)", );

Which just boils down to this slightly longer code that I write when I don't have such trivial wrappers handy:

$db->prepare( join ' ', "SELECT", join( ', ', "this", "that", "theother", "COUNT(*) as things", ), "FROM", join( ' ', "foo", "LEFT JOIN bar USING( id )", ), "WHERE", join( ' AND ', "? <= stamp", "stamp < ?", @exclude ? "this NOT IN ( ?? )" : (), ), "GROUP BY this, that, theother", "ORDER BY that, this", "LIMIT $size OFFSET $skip", "HAVING 1 < count(*)", );

(Except that I like to build the SQL first rather than pass it directly to prepare(), so that I can easily get literal SQL in case I need to play with it interactively in a simple SQL tool. This includes replacing the placeholders with quote()d values.)

I find that scales much better as maintenance takes its toll.

I've also repeatedly suffered due to multi-line SQL dripping with whitespace, especially leading whitespace, tripping up perhaps somewhat naive DB tools I've needed to use to diagnose DB problems.

So I still feel quite justified in discouraging others from just running off and using here-docs, especially when I'm not planning on going on for thousands of words on how to avoid the many pitfalls.

- tye        


In reply to Re^8: Quote and Quote-like Operators (here-docs break) by tye
in thread Quote and Quote-like Operators by Xiong

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.