Prev: piped open and shell metacharacters
Next: FAQ 8.27 What's wrong with using backticks in a void context?
From: Ben Morrow on 31 Jul 2010 14:16 Quoth J�rgen Exner <jurgenex(a)hotmail.com>: > "Thomas Andersson" <thomas(a)tifozi.net> wrote: > >J�rgen Exner wrote: > > >The loop has been rewritten and workds as intended now, using last to exit > >on the two possible conditions. Now look like this: > > > >while (1) { > > Ouch, this hurts! Usually this line indicates a deamon which is never > supposed to terminate. Not necessarily. (It might be more idomatic to spell it for(;;), but that's beside the point.) > > my $page = get "$pbase?page=$pcnt&pid=$pid"; > > last if $page =~/No sorties/; > > # Store grabbed webpage into the file > > append_file( "c:/scr/$pid.txt", $page ) ; > > last if $page =~/"sid=$lproc"/; > > # Update page number and grab next. > > $pcnt++; > >}; > > Why not move the loop condition into the loop condition? > > my $page = get "$pbase?page=$pcnt&pid=$pid"; > while ((!$page =~/No sorties/) and (!$page =~/"sid=$lproc"/)) { > append_file( "c:/scr/$pid.txt", $page ); > $pcnt++; > $page = get "$pbase?page=$pcnt&pid=$pid";} > } Yuck, you've just done the 'get' twice. DRY is *far* more important than 'structured programming', unless you're going to attempt to prove the program's correctness. > Yes, I know the condition could be formulated better, but I transformed > it as little as possible to demonstrate how the exit() cond can > trivially be moved into the while() cond. Not without duplication of code. Ben
From: Martijn Lievaart on 31 Jul 2010 14:27 On Sat, 31 Jul 2010 09:35:27 -0700, sln wrote: > Beware that if $page is generated html, using a regex on it as in > > $page !~ /No sorties/i > $page =~ /$sid_rx/ > > can be done, but only after it is parsed. Why? Are you afraid the same text occurs inside a tag? > It can be parsed with regex's However, that is a bad isea generally. HTH, M4
From: Peter J. Holzer on 31 Jul 2010 15:19 On 2010-07-31 16:42, J�rgen Exner <jurgenex(a)hotmail.com> wrote: > "Thomas Andersson" <thomas(a)tifozi.net> wrote: >>The loop has been rewritten and workds as intended now, using last to exit >>on the two possible conditions. Now look like this: >> >>while (1) { > > Ouch, this hurts! Usually this line indicates a deamon which is never > supposed to terminate. Maybe. Personally I never use while (1), I prefer for (;;) instead. But neither implies that the loop is really infinite: It may (and often is) be left with last or return. >> my $page = get "$pbase?page=$pcnt&pid=$pid"; >> last if $page =~/No sorties/; >> # Store grabbed webpage into the file >> append_file( "c:/scr/$pid.txt", $page ) ; >> last if $page =~/"sid=$lproc"/; >> # Update page number and grab next. >> $pcnt++; >>}; > > Why not move the loop condition into the loop condition? > > my $page = get "$pbase?page=$pcnt&pid=$pid"; > while ((!$page =~/No sorties/) and (!$page =~/"sid=$lproc"/)) { > append_file( "c:/scr/$pid.txt", $page ); > $pcnt++; > $page = get "$pbase?page=$pcnt&pid=$pid";} > } > > Yes, I know the condition could be formulated better, but I transformed > it as little as possible to demonstrate how the exit() cond can > trivially be moved into the while() cond. You also demonstrated how easy it is to inadvertently change the logic in the process. Thomas' code exited *after* saving the page containing sid=$lproc, yours exits *before* saving it. I don't know which one is correct, but they are definitely not the same. I also strongly disagree that it is a good thing to transform a loop of the form for (;;) { get data; last unless condition; process data; } into get data; while (condition) { process data; get data; } It duplicates the "get data" part which makes it easy to introduce bugs by only changing one of the parts. Perl has "next" and "last" for a reason. Use them. In many cases both the duplication and the use of "last" can be avoided by using a function call: sub get_data { get data; return condition; } while (get_data()) { process data; } But that doesn't always work. Among the nice properties of last and next is that they can be easily cascaded: while (get_data()) { next unless condition1; process data; next unless condition2; process data some more; next unless condition3; a little more and we are done; } > BTW: space characters are very cheap, I just saw a them on sale at > Costco. Fell free to use as many as you like to make your code more > readable. Full ACK. hp
From: Tad McClellan on 31 Jul 2010 15:31 Ben Morrow <ben(a)morrow.me.uk> wrote: > > Quoth "Thomas Andersson" <thomas(a)tifozi.net>: >> > Also: get into the habit, now, of keeping you filehandles in proper >> > variables. It will make life easier later. >> > >> > open my $FILE, ">", "..." or ...; >> But if I createa variable of the filehandler like this, ^ ^ > Yes, you are misunderstanding. If you create $FILE like that, it will > contain a filehandle. Note that these are called a "filehandle", without an "r". You should probably avoid using the word "handler" unless you are talking about handlers. That is, the term has a particular meaning to programmers: http://en.wikipedia.org/wiki/Event_handler http://en.wikipedia.org/wiki/Signal_handler -- Tad McClellan email: perl -le "print scalar reverse qq/moc.liamg\100cm.j.dat/" The above message is a Usenet post. I don't recall having given anyone permission to use it on a Web site.
From: J�rgen Exner on 31 Jul 2010 15:32
Sherm Pendley <sherm.pendley(a)gmail.com> wrote: >J�rgen Exner <jurgenex(a)hotmail.com> writes: > >> If this is the end condition for the loop then it would help even more >> if your put it in the condition for the loop. >> >> while (........ and ($page ne $endstring)) { > >It's a judgement call. Sometimes, especially if there are several con- >ditions, it can make more sense to use last: > > while(foo && bar && baz) > > while(1) { > last unless foo; > last unless bar; > last unless baz; > ... > } > >Which form to use is best judged on a case-by-case basis, with the >goal being readability. I would almost agree. But when _I_ see a while() loop, then I am looking at the while() condition to determine, under which condition the loop is being executed and also to determine which post condition will hold true after the loop has terminated. Personally I am very much in favour of having one entry and one exit from a loop rather than searching for an unknown number of exit points scattered somewhere deep down in the who-knows-how-long loop body. It just makes reasoning about the loop a lot easier. But it's certainly a matter of style, at least as long as you don't try to do any formal program verification. Each additional exit point adds another proof requirement. jue |