CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
For Loop problem

 



AlanB
Novice

Jun 2, 2003, 1:22 AM

Post #1 of 14 (2314 views)
For Loop problem Can't Post

I am trying to use the For loop in a script and have encountered something I don't understand.

Having set a variable $maxrecords to the number of records in a database the following loop seems to work OK:

for ($i=0; $i<$maxrecords; $i++) {
do something
}

However if I change it to read:

for ($i=0; $i=$maxrecords; $i++) {
do something
}

it just goes into an infinite loop!

Please could someone explain why this would happen

Thanks

Alan


davorg
Thaumaturge / Moderator

Jun 2, 2003, 1:56 AM

Post #2 of 14 (2313 views)
Re: [AlanB] For Loop problem [In reply to] Can't Post

The second part of the "for" statement (your, "$i < $maxrecords" code) controls the execution of the loop. Each time round the loop Perl checks the value of the loop and it exits the loop when the expression is true.

In your first example, $i is increased each time round the loop, and the loop is executed as long as $i is less than $maxrecords. Once $i gets to the same value as $maxrecords the loops exits.

In your second example you are doing something strange. Each time round the loop, you are setting $i to the value of $maxrecords. As $maxrecords is a positive integer, you loop condition will always be true so your loop will never exit.

So that's probably not what you wanted it to do. ow were you hoping that the loop would act?

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


AlanB
Novice

Jun 2, 2003, 2:09 AM

Post #3 of 14 (2311 views)
Re: [davorg] For Loop problem [In reply to] Can't Post

Hi Dave

Right I can begin to see what you are getting at now. So what you are saying is that the For loop works on the basis of:

$i=0 - set control to 0 for the first time
$i++ = increment i for each record
$i<$maxrecords - is $i still less than $maxrecords - if so keep going.

I was trying to work on the old principle of my old days of BASIC programming where For I=0 to $maxrecords would execute from 0 to whatever $maxrecords contained.

I assumed that Perl worked on the same way so when I see:

(starting value; terminating value; increment value)

as a Perl example I naturally thought that by putting

(0, $maxrecords, ++) would do the same thing i.e. start at 0 do until $maxrecords, incrementing each pass by 1.

I did not realise that $i=$maxrecords would actually change the value of $i !!!

Cheers

Alan


davorg
Thaumaturge / Moderator

Jun 2, 2003, 2:48 AM

Post #4 of 14 (2309 views)
Re: [AlanB] For Loop problem [In reply to] Can't Post

I see what you mean, but Perl isn't very much like BASIC at all. The "for" loop is borrowed from C.

I think you'd be better off with a "foreach" loop here.

Code
foreach my $i (0 .. $maxrecords) { 
# do stuff
}


--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


AlanB
Novice

Jun 2, 2003, 2:52 AM

Post #5 of 14 (2308 views)
Re: [davorg] For Loop problem [In reply to] Can't Post

Thanks Dave

Is the snippet you included exactly how you would encode it in the script? (0 .. $maxrecords)??


davorg
Thaumaturge / Moderator

Jun 2, 2003, 3:41 AM

Post #6 of 14 (2307 views)
Re: [AlanB] For Loop problem [In reply to] Can't Post


In Reply To
Is the snippet you included exactly how you would encode it in the script? (0 .. $maxrecords)??


Yep. The "foreach" loop iterates thru a list of values setting the loop variable ($i in this case) to each value in the list in turn.

The range operator ('..') creates a list of integers from the first value to the second value (inclusive).

The two constructs work well together for the kinds of loops that you are doing.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


AlanB
Novice

Jun 2, 2003, 4:05 AM

Post #7 of 14 (2305 views)
Re: [davorg] For Loop problem [In reply to] Can't Post

Excellent!!

Thanks very much Dave
(I'm sure I'll be back with others!!!)

Alan


Jane
Novice

Jun 2, 2003, 12:56 PM

Post #8 of 14 (2293 views)
Re: [davorg] For Loop problem [In reply to] Can't Post

 davorg wrote...


Quote
"As $maxrecords is a positive integer, you loop condition
will always be true so your loop will never exit".



Negative values are also true here. Zero is false. So the problem is not strictly due to $maxrecords being positive, rather to the fact that it's true.

----------------------------------------------------------------------
davorg wrote...


Code
  foreach my $i(0 .. $maxrecords){ 
# do stuff
}


----------------------------------------------------------------------

But 0..$maxrecords will cause an extra iteration. Try 1..$maxrecords.

AlanB. I don't know but it looks as though you want the block to execute provided that $i is less than or equal to $maxrecords. You should use <= for this. However, since you've initialised your counter to 0, all you need is < because for example, supposing there are 20 records in your database, then $i will increment through 0..19, and the condition will be reviewed 20 times.

In Perl, '=' is the assignment operator, ie. the value on the RHS is copied to the location specified on the LHS.
'==' is the equivalence operator.


Code
 my $i = 0; 
until( $maxrecords-- == $i ){
...
}

until( $i++ == $maxrecords ){
... }

... until ! $maxrecords--;






Perl provides a plethora of methods to do what you want...


Code
     while( $maxrecords-- ){ 
... }

... while $maxrecords--;



...and more.

Jane.

map{$,--%(5>>1)^0?push@y,$_:unshift@y,$_}sort(Hacker=>another=>Perl=>Just);for(1&1=>1|0){push@y,shift@y}print"@y"


Paul
Enthusiast

Jun 2, 2003, 2:44 PM

Post #9 of 14 (2290 views)
Re: [Jane] For Loop problem [In reply to] Can't Post


Quote
So the problem is not strictly due to $maxrecords being positive, rather to the fact that it's true.


Dave never said it was strictly due to it being positive...he said the result will be true because $maxrecords is positive, which is correct =)


(This post was edited by Paul on Jun 2, 2003, 2:44 PM)


Paul
Enthusiast

Jun 2, 2003, 2:45 PM

Post #10 of 14 (2288 views)
Re: [AlanB] For Loop problem [In reply to] Can't Post

The simple answer to your problem is to use == instead of =

Wink


AlanB
Novice

Jun 2, 2003, 2:48 PM

Post #11 of 14 (2285 views)
Re: [Paul] For Loop problem [In reply to] Can't Post

Nope!! Tried that - same infinite loop resulted!!


Paul
Enthusiast

Jun 2, 2003, 2:51 PM

Post #12 of 14 (2283 views)
Re: [AlanB] For Loop problem [In reply to] Can't Post

If $maxrecords is numeric it can't/shouldn't loop forever unless it is negative.


AlanB
Novice

Jun 2, 2003, 2:54 PM

Post #13 of 14 (2281 views)
Re: [Paul] For Loop problem [In reply to] Can't Post

I know it shouldn't - you know it shouldn't - but does Perl know it shouldn't!!!!

It was the most obvious answer when all else failed and it just did not work the way it should have done. $maxrecords is most definitely positive - really strange one this


Jane
Novice

Jun 3, 2003, 10:32 AM

Post #14 of 14 (2272 views)
Re: [Paul] For Loop problem [In reply to] Can't Post

"As $maxrecords is a positive integer, you loop condition will always be true"...

...means...

"As $maxrecords > 0, you loop condition will always be true"

Yes, $maxrecords is a positive integer, but that's not the only reason why the condition could be true. I think that something like "As $maxrecords is not zero" would be more informative.

If x = $maxrecords, v = value (instead of condition) and -> means 'implies', then we can express the statement above mathematically as

v = 1 if x > 0 -> v = 0 if x <= 0

This is clearly incorrect because we know

v = 1 if x < 0, x > 0

i.e. v = 1 if x != 0

So if v is a function of x, where the range of f(x) is f(x) = 1, then for example

f:x --> x/x for x != 0

and

v = f(x) = x/x for x is IR, x != 0

Jane.
Think |negatively|
map{$,--%(5>>1)^0?push@y,$_:unshift@y,$_}sort(Hacker=>another=>Perl=>Just);for(1&1=>1|0){push@y,shift@y}print"@y"

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives