Saturday, 5 January 2008

Ruby Has No "for" Loop - Woo Hoo!

I held onto my hat when I heard this one. I use the 'for' loop in Java a lot. Probably more than I ought. 'How will this work' I thought? No 'for' loop? Nonsense ...


When I saw it I liked it. Its often said (by me too earlier) that one of the reasons Ruby is so great is that it reads. Well, here's another example of just that. I like.

6 comments:

Q said...
This comment has been removed by the author.
Q said...

hey man,
I'm coming from a java background and learning ruby as well. as elegant and simple as ruby iterators are, for the life of me i can't see an easy (two line) way of reproducing this exact java loop in ruby

for (int i=150; i > 0; i-=10)
...do something with i...

so....
1. going down
2. stepping by more than 1
3. operating exclusively (like 150...0)

the closest one gets is
150.step(0, -10) {|i| .......}
but that goes all the way to 0 and doesn't stop at 10

i know i could just use 1 instead of 0 but that isn't quite the same as the java for loop (and doesn't have the ruby elegance)

seems like (150...0).step(-10) should work but Range#step doesn't take negative numbers

this is really puzzling me
any ideas?

xmlblog said...

q,

Write your own step. :)

class Range
  def by(amount, &block)
... exercise for you ...
  end
end

(150...0).by(-10) do |current|
... your code here
end

Tim Endres said...

I have an array of dates and I want to process that array from the beginning up to the first to last date. In other words, I want to process date[0] to date[date.length-2]. The .each construct does not help, unless I add some hideous counter that I use to compare inside my loop. Seems very clumsy.

Is there a better way to write this code:

cntr = 0
dates.each do |dt|
   ...process date...
   cntr = cntr + 1
   break if cntr > dates.length - 2
end

xmlblog said...

dates[0..-2].each do |d|
...
end

Bug said...

Dude, Ruby has a for loop.