Can this be done (by a noob :))

U

Uri Guttman

JE> Ouch, this hurts! Usually this line indicates a deamon which is never
JE> supposed to terminate.

not in my book. it just means an infinite loop. check inside for calls
to last. fine with me and remember, i told him to do this! :)

uri
 
M

Martijn Lievaart

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
 
P

Peter J. Holzer

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.

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
 
J

Jürgen Exner

Sherm Pendley said:
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
 
J

Jürgen Exner

Martijn Lievaart said:
Beware that if $page is generated html, using a regex on it as in [...]
It can be parsed with regex's

However, that is a bad isea generally.

Or more to the point: parsing HTML, which is _context-free_, using true
_regular_ expressions is impossible.
And even using the much more powerful enhanced REs from Perl is nothing
a sane mind would attempt.

jue
 
J

Jürgen Exner

Ben Morrow said:
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.


Not without duplication of code.

Well, fine, then just move the get() call into the condition itself:

while (($page = get "$pbase?page=$pcnt&pid=$pid")
and (!$page =~/No sorties/)
and (!$page =~/"sid=$lproc"/)) {

Personally I don't particularly like this approach because the get()
doesn't contribute to the condition and exists only for its side effect,
but there is no code duplication any more.

jue
 
J

Jürgen Exner

Sherm Pendley said:
I think we agree more than not - note that I grouped the conditionals
at the top of the loop body, with the ellipses representing additional
code appearing after them. I wouldn't scatter them throughout the loop
body, unless I had a *very* good reason for doing so.

:)

jue
 
J

Jürgen Exner

Ben Morrow said:
I don't know much about proving programs, but do additional exit points
really make it any harder than stuffing everything into the conditional?
Either way, you end up having to deal with the complexity of the
algorithm somewhere.

Well, depends. If it's just a top-level series of
last if (C1);
last if (C2);
last ....
then no, not really. You just collect all of them and you know that
after the loop at least one of them is true, i.e.
C1 or C2 or C3 or ...

The tricky and rather tedious part are those assertions derived from the
rest of the code that was executed until each last() call somewhere deep
down a deeply nested loop with many conditionals. Those have to be
collected, too, or'ed too, and then simplified. And that's a pain in the
lower rear.

jue
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,216
Latest member
topweb3twitterchannels

Latest Threads

Top