in reply to Re: Comment a block that match a keyword
in thread Comment a block that match a keyword

There's a couple of things That smell bad to me about this. They're personal things; I don't have any doubts that the code works. It's just things that trouble me:

I'd be happier with a do block, rather than a bare block. Perhaps it's just me :)

Like I said, personal things.

update: added stuff about do after further thought

Replies are listed 'Best First'.
Re^3: Comment a block that match a keyword
by BrowserUk (Patriarch) on Aug 17, 2007 at 01:45 UTC

    I wasn't particularly enamoured with it, hence my "could be refactored" comment. The reason I didn't refactor it at the time was I couldn't see a nice way how to.

    Noting your "personal preferences" emphasis, I hope you don't mind if I respond with my take on things?

    1. a block pretending to be a loop, and the use of redo and last therein.

      Update: Everything in here is wrong. See the responces below

      The real problem here is Perl's lack of a post-condition loop construct.

      As was pointed out to me here a couple of years ago, unlike pascal's repeat ... until cond();, Perl's do{ ... } while/until cond(); construct tests the condition before entry to the loop body, and will prevent entry ever happening if the condition isn't met. That leaves us with the unfortunate situation, when we need to execute the loop body at least once, of duplicating that loop body:

      # do stuff do { # the same 'do stuff' as above. } while cond;

      And that repetition of 'do stuff' is a problem. In this case, having read a line at the top of the while loop, we need to

      • do some stuff (initialise out parens count from the first line)
      • enter the loop construct
      • do some more stuff (prepend the comment card and print)
      • read the next line, check for eof.
      • chomp the line we just read.
      • Do some more stuff (adjust the parens count from the new line)
      • decide whether to loop or not

      And the only way I know how to do that in perl (without artificial means like setting flags and/or double condition tests) is redo.

      You said: I'd be happier with a do block, rather than a bare block., but that doesn't work:

      #! perl -slw use strict; my $i =0; do{ print ++$i; redo if $i < 5; }; __END__ c:\test>junk2 1 Can't "redo" outside a loop block at c:\test\junk2.pl line 7.

      You'd have to do

      #! perl -slw use strict; my $i =0; do{{ print ++$i; redo if $i < 5; }}; __END__ c:\test>junk2 1 2 3 4 5

      That is, embed a bare block within the do block, and that is redundant and very obscure.

      You could adopt a Perl 6 like construct:

      LOOP:{ ... redo LOOP; }

      which could be construed as clearer. But frankly, redo in a bare block is a perfectly valid and useful construct and, I think, it is better to just become familiar with it than to obscure it. Indeed, it is actually the most flexible looping construct. It can be used to construct all many other looping constructs Perl has. Even the much decried but extremely flexible C-style for loop with its otherwise unique ability to vary multiple indexes concurrently.

      ## draw the diagonals for( my $x=0, my $y=0; $i < $xMax; $x++, $y++ ) { draw( $x, $y ); +} for( my $x=0, my $y=$yMax; $i < $xMax; $x++, $y-- ) { draw( $x, $y ); +}

      It's a little used feature, but when you need it, you need it:

    2. chomp that isn't the first thing done in the "loop". I'd have put it first, even if any subsequent print (etc) had to include \n.

      Hm. I'm not sure what the position of chomp has to do with the loop construct. The chomp has to follow the readline. The readline has to occur in the middle of the loop.

    I'm still not happy with the construction I posted, but I haven't come up with a better one.


    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.

      You might want to test your ideas about do{ STMTs }while( EXPR );. The while() condition actually is tested at the end of the loop, ensuring that the body of the loop is always run at least once.

      The 'problem' with it is that it isn't a "loop" as far as next, redo, and last are concerned (due to somewhat obscure implementation details).

      But it is a construct I find useful, not just some redundant alternative to while( EXPR ){ STMTs } and STMT while EXPR; (which both test before each iteration).

      - tye        

      Whadda yer know. I made this same error 3 years ago, and despite being corrected, and accepting that correction from the ultimate authority, I'm still making it.

      Does that say something about me? Or just confirm TimToady's reasoning for ditching the do{ ... } while construct.

      For those not following along.

      This

      my $i = 0; while( $i < 5 ) { print ++$i; } 1 2 3 4 5

      And this

      my $i = 0; print ++$i while $i < 5; 1 2 3 4 5

      Produce the same output.

      And so do $i = 0; until( $i >= 5 ) { print ++$i }

      And $i = 0; print ++$i until $i >= 5;

      And $i=0; ++$i and print( $i ) while $i < 5;

      And $i=0; ++$i, print( $i ) while $i < 5;

      And even this $i=0; do{ ++$i; print( $i ) } while $i < 5;

      But then suddenly, whilst $i=0; print( $i ) while $i++ < 5; this does.

      This

      $i=0; do{ print( $i ) } while $i++ < 5; 0 1 2 3 4 5

      doesn't.


      So, somewhere back there I've reached the conclusion that do{  } while is too subtle even for my tastes and stopped using it. As a result, I convinced myself that "Perl doesn't have a post-condition loop".

      As you can see, I'm wrong. But for good reasons, and in line with those of some other people I respect, I'll continue to mentally deprecate it's usage.

      With luck, this will act as an aide memoire to cause me not to voice my internal deprecation Perl does not have a post-condition loop out loud.


      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.