I had a bit of trouble going through the perldocs when I started on perl as it is all rather confusing at that stage. But it is definetly worth it. I was avoiding going back again and then noticed some links to the perltut posted by a distinguished monk, so I revisited them.

Having been writing some initiate level subroutines I was amazed at some of the basic syntax and structure practices I was failing to include in my code. The shear feeling of elation I have from just reading a few nicely laid out tutorials is beyond description. Send $40 dollars now and you may have the opportunity to become the next beautified initiate at perlmonks.org ... (joking)

Here's a small before and after - the differences are subtle but extremely satisfying.

before:
sub adedtear{ open(my $prfore, "<", "../editsite2/preview.html") or die "couldn't o +pen preview for read in sub adedtear: $!\n"; while(my $line=<$prfore>){ if($line =~ m/<\!--texts001-->/){ $flag=1; } if($flag == 1){ if($line =~ m/<\!--text[s|e]/){ $line=$line; } else{ $line =~ s/<br\/>//; $linevalis .= $line; $line = ""; } } if($line =~ m/<\!--texte/){ $flag=2; } } close $prfore or die "couldn't close prfore: $!\n"; print $bar $foo->textarea({-id=>'t001', -name=>'none', -value=>"$linev +alis"}) or die "cant print linevalis into textarea cgi: $!\n";&n; }
after:
sub adedtear{ open(my$prfore, "<", "../editsite2/preview.html") or die "couldn't op +en preview for read in sub adedtear: $!\n"; LINE: while(<$prfore>){ if(/<\!--text[se]\d{3}-->/){ $flag=1; next LINE; } if($flag){ unless(/<\!--texte/){ s/\D{5}\s+$/\n/; $linevalis .= $_; } else{$flag=0;} } } close $prfore or die "couldn't close prfore: $!\n"; print $bar $foo->textarea({-id=>'t001', -name=>'none', -value=>"\n$lin +evalis"}) or die "cant print linevalis into textarea cgi: $!\n";&n; }

Replies are listed 'Best First'.
Re: Another reason for perl beginners to read perldocs
by GrandFather (Saint) on Jul 02, 2011 at 23:20 UTC

    I'd avoid statement labels ('LINE' in your sample) unless they are required. Especially in a small scope the target of loop commands is clear in any case and adding statement labels makes it look like more is going on than is actually the case.

    Bare in mind that the Perl documentation has evolved over a long period of time and has contributions from many people with different personal coding idioms. Some (much?) of the sample code in the Perl docs does not reflect common Perl idiom, but is a pragmatic way of illustrating some specific language feature. You will often see use of old style bare word file handles for example, or C style for loops. That doesn't mean that those style elements are current best practice however!

    True laziness is hard work
      A good rule of thumb is, if you have 2 or more loops, you might use a label. You need a label if you want to exit an outer loop from an inner loop :)

      Another good rule of thumb is, if you have 2 or more loops, start turning inner loops into function calls :)

        I would strengthen your first rule of thumb to: "You should only use a label if you have two or more nested loops and need to exit from an inner loop to an outer loop".

        I very much agree with your second rule except I would widen it to include any nested code: "If you have nested flow control blocks consider moving inner blocks into functions".

        True laziness is hard work
      I'd avoid statement labels ('LINE' in your sample) unless they are required. Especially in a small scope the target of loop commands is clear in any case and adding statement labels makes it look like more is going on than is actually the case.

      Here's Essential Practice number 4 of Damian Conway's Ten Essential Coding Practices:

      4. Label every loop that is exited explicitly, and every next, last, or redo.

      I adhere to this best practice except in the most trivial circumstances. Whenever there's a natural, logical label to use (e.g., LINE, RECORD, ROW, FROG), I use it. It makes my intentions explicit and clear.

      (See Perl Best Practices.)

Re: Another reason for perl beginners to read perldocs
by dcmertens (Scribe) on Jul 06, 2011 at 16:44 UTC

    I don't see any problem with labeling lines with something descriptive. I do this in my code because it makes the meaning more legible in standard English. However, I would omit the semicolon in the else clause, so it would read

    else {$flag = 0}

    I typically use such one-line blocks in evals like

    eval {this_may_die();};

    Removing all the unnecessary punctuation makes it much nicer, in my opinion:

    eval {this_may_die};
Re: Another reason for perl beginners to read perldocs
by thirdm (Sexton) on Jul 09, 2011 at 16:28 UTC
    I find flags make flow hard to work out. Maybe it's only the way I think (or don't). What do you think of the following version of your loop, presuming I've successfully captured what you wanted to have happen?
    my $start_delim = qr/<\!--text[se]\d{3}-->/; my $end_delim = qr/<\!--texte/; while (<$prfore>) { if (/$start_delim/) { do { $_ = <$prfore>; } while !eof and /$start_delim/; for ( ; !eof and !/$end_delim/; $_ = <$prfore>) { s/\D{5}\s+$/\n/; $linevalis .= $_; } } }

      yes the inherent problem is not to read in the start and end delimiter. I solved this by using if else conditionals which were refined down from using while/do statements that I had improperly constructed and ave me erroneous results. I have not yet practiced while/do statements especially with the !not operator. This looks like a very clean and 'flag-less' way to achieve the outcome of extracting the interior lines. In my exercise I was excited at the effective use of the boolean sense of the flag rather than in the original where I had employed the sense of comparison.(using 1/0 and not 1/2).

      I am intrigued by the for ;!oef and !/$end_delim; conditional. I would not have come up with this as the for conditional you have provided only has two conditions where I am used to it having the incremental three. Though I recently put an array variable solely into a for() and it acted like a foreach. You have left out the initial value and used a non-incremental central conditional. However in this way it makes the for a lot more 'english' as you are saying 'for the remaining options, (after the do has exited) read in the line until either are returned true and exit before reading the delimiter in'.

      so apart form the idea that the delimiters you are using are themselves boolean I can understand that you mean there is no need to add in unnecessary additional flags. Also in my case I would be fairly certain of not requiring eof delimiter conditions but it is good to see how do / while is used in practice. One of my aims is to expand the use of control structures from one of only using if/else conditionals.

      in reference to LABELS: there may be the sense that overuse is in play but that is to help my understanding rather than for elegance. Though it appears that someone has something to say about labelling all too?

      for the curious, and because I can't get to sleep thinking about do whiles - here follows the for with the sole array variable. It is a starting attempt to index array data from an initial array reference - as in what's in there? with a litle imagination to be developed to extract hash index too. I am aware this is most likely fully developed in Data::Dumper.

      use strict; use warnings; my @AoA= ( #actual [ "fred", "barney", "pebbles", "bambam", "dino", ], #ref [ "george", "jane", "elroy", "jenks", ], #ref [ "homer", "bart", "marge", "maggie", ], #ref ( "dave", "sam", "babby", "nan",), #actual ); my $refAoA = \@AoA; #refofactual for (@$refAoA){ #magic if(ref $_){ print ref $_.$/; for(@$_){ if($_ eq "elroy"){ print $_."if event".$/; }else{print $_.$/;} } }else{ for($_){ print $_; } } print $/; } do{$heep++} while !$leep; exit(0);

      My thinking is that the for would treat the array in a scalar context and produce an error but this looped through the arrays ref and actual and prints them out.