Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Re^6: Quote and Quote-like Operators (heredocs break)

by tye (Sage)
on Dec 16, 2011 at 16:26 UTC ( #943966=note: print w/replies, xml ) Need Help??

in reply to Re^5: Quote and Quote-like Operators
in thread Quote and Quote-like Operators

Even with all of that clever work, go ahead a 'shift' any of those blocks of code over and watch your heredoc break. Your heredocs above break indentation (your terminators aren't indented). And (re)indentation breaks your heredocs.

Perhaps worse, trailing whitespace can break a Perl heredoc. Plenty of reason to avoid using them in code I plan to maintain.

- tye        

  • Comment on Re^6: Quote and Quote-like Operators (heredocs break)

Replies are listed 'Best First'.
Re^7: Quote and Quote-like Operators (heredocs break)
by Your Mother (Archbishop) on Dec 16, 2011 at 17:21 UTC

    It's even worse than that. I recently discovered that an incorrect closing quote in a string will break it. So I insist on not using strings in code I plan to maintain.

    <but class="seriously">I don't disagree that acrobatics to make heredocs appear as normal code flow edges toward egregious.</but>

      I recently discovered that an incorrect closing quote in a string will break it.


      Things where "incorrect" can break it: everything. Things where "trailing whitespace" can break it: almost nothing, and for good reason. On the extremely rare occasions when I find something where trailing whitespace matters, it is usually just admitted as a bug. I can't even think of any cases of that right now except for heredocs.

      I can't even think of anything where

      one space

      makes a difference compared to

      two spaces

      And you can actually see that difference.

      And, yes, even ignoring all of that, making it easy to get the delimiter wrong for a heredoc is much worse than getting the delimiter wrong for a string.

      sub flutz { # ... my $blob= <<END; ... END # ... } sub flortz { # ... my $blob= <<END; ... END } if( int rand 2 ) { flortz(); }

      compiles completely fine. Of course, it often produces:

      Undefined subroutine &main::flortz called at - line 16.

      when you run it since I wrote the example to make it relatively trivial to notice that the intervening code has just "gone away".

      But I can't even make this example demonstrate why because the important part is invisible. (Update: Even highlighting the above code doesn't show the trailing whitespace, at least for my environment.)

      Construct an example where getting the closing quote wrong compiles without error. It won't be nearly as easy as this.

      And while you are trying, you'll probably have a chance to notice that Perl often goes out of its way to help you see your mistake via something like:

      blah blah blah at - line 13, near "blah" (Might be a runaway multi-line '' string starting on line 4)

      This is done because experienced programmers figured out that when getting the closing delimiter wrong it can be hugely frustrating to find the source of the problem.

      I'm not sure whether you were dismissive just to be funny or if you actually were trying to be dismissive. But I responded because I didn't want other readers to dismiss the point based on your clever dismissal, preventing them from thinking much about the point and realizing how crazy significant trailing whitespace is.

      - tye        

        You'll probably deride the notion, but I've long since had my editor configured to 'strip trailing whitespace on save' when editing source files for every programming language I use.

        I was seriously frustrated by the effects of the presence of a space after the \ on a continuation line. Once bitten, twice shy.

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        The start of some sanity?

Re^7: Quote and Quote-like Operators (heredocs break)
by runrig (Abbot) on Dec 16, 2011 at 22:00 UTC
    Many of the developers @my_work use the 'clever':
    .... my $here_doc = '....END'; stuff here ....END

    Along with clever trim leading whitespace code...which I I use heredocs, but ONLY on the left margin. I've become fond of syntax highlighting, so any incorrect trailing marker is (usually) obvious. I've also taken to using some vim heredoc highlighting tips and always use the terminators SQL, XML, and HTML when appropriate.

    If I have a heredoc in a sub, I move it out of the sub, e.g.

    my $sql = <<SQL; SELECT * FROM TABLE SQL sub do_stuff { ... $dbh->execute($sql); }
    If the $sql needs to be dynamic, I'll probably change it to a sprintf template, and call sprintf in the sub.

      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        

Re^7: Quote and Quote-like Operators (heredocs break)
by demerphq (Chancellor) on Dec 27, 2011 at 16:51 UTC

    I totally agree with you. Heredocs, as implemented in Perl5 are a maintenance problem waiting to happen. I frankly cant stand it when I indent a chunk of code and breaks in all kinds of bizarro ways because it has stupid here docs in it.


Log In?

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (2)
As of 2022-06-25 16:24 GMT
Find Nodes?
    Voting Booth?
    My most frequent journeys are powered by:

    Results (83 votes). Check out past polls.