tags:

views:

101

answers:

5

Dear Colleagues

I am a newie in Ruby and I am facing a problem regarding "each"-like loops. Suppose a code like the following

startIndex = 1
endIndex = 200

(startIndex..endIndex).each do |value|
   p value
   if value>150 then endIndex=100
end

When I run the code it will run until 200, not until 150. Is there any way to change the limits of the loop range dynamically in Ruby?

Thanks in advance for your help

Tryskele

+6  A: 

Why not just break?

(startIndex..endIndex).each do |value|
    p value
    break if value>=150
end

'cause it's really bad practice to dynamically change loop limits.

F0RR
A: 

No.

This is almost certainly not what you want to do.

What problem are you trying to solve?

hobodave
hobodave,You are right, this was an example. The fact is that I am parsing the reply of a web server that is split in different pages (i.e. uris). I can only know the number of pages after I made the parsing of the first page. That is why I need to change the ending range of the loop dynamically. I was trying to figure out how to do it using a "each"-like loop. Is there any other way to do it?Thanks everyone for your replies!Tryskele
Tryskele
Well, if you always know the number of pages after first initial request, you can do something like (get_number_of_pages).each { |page| ... } where get_number_of_pages is a block or another function that gives you the list of pages to look at. It might even return uris for other pages if possible. That would make your code more obvious.
Priit
A: 

If you just want to stop printing it at 150, these might work.

startIndex = 1
endIndex = 200

(startIndex..endIndex).each do |value|
   p value if value <= 150
end

or

startIndex = 1
endIndex = 200

(startIndex..endIndex).each do |value|
   p value
   if value >= 150 
     break
   end
end
nowk
+2  A: 

No, what you are trying to do won't work. However, it is also completely unnecessary, since there is a much better, idiomatic way to do the exact same thing you are trying to do:

p *(1..150)
Jörg W Mittag
+3  A: 
startIndex= 1
endIndex= 200

range= (startIndex .. endIndex) # => 1..200

endIndex= 150
range # => 1..200

(a..b) creates an Object of the Range class. A Range Object does not hold pointers to the variables you pass. It rather hold's references to the objects, the variables points to. If you change the variable, so the variable hold a reference to another object, the Range still holds the reference to the old object. So you can change the Range by changing the object itself. But there is no way to change an Integer once it's created.

a= "abc"
b= "def"
range= (a..b) # => "abc".."def"
b.sub!("e", "$")
range # => "abc".."d$f"

If the only thing you want to do is escape from the loop, you could just use break

(a..b).each do |v|
  break if something
end
johannes