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

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.

    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.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^4: Comment a block that match a keyword (do)
by tye (Sage) on Aug 17, 2007 at 02:12 UTC

    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        

Re^4: Comment a block that match a keyword
by BrowserUk (Patriarch) on Aug 17, 2007 at 10:33 UTC

    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.