views:

278

answers:

2

(Sorry for the newbie question.) In Ruby, what is the difference between the loops:

@cars.each do |car|

and

for car in @cars do

?

is there a difference in efficiency, or why do we need two (or more) ways to express the same thing? The second way seems more elegant/natural to me, but I may be missing some crucial observation, why the first may be the better choice.

+2  A: 

I think it is just syntactic sugar. It is functionally equivalent, and I am not aware of any implementation difference in the interpreter.

Note - you can lose the 'do' on the second one.

DanSingerman
+17  A: 

More people use the @cars.each notation because that generalizes to other methods (like #inject, #each_with_index, #map, etc, as well as non-iterator callbacks).

for/in is mainly just syntactic sugar for #each. The main difference in how the two work is in variable scoping:

irb> @cars = %w{ ford chevy honda toyota }
#=> ["ford", "chevy", "honda", "toyota"]
irb> @cars.each { |car| puts car }
ford
chevy
honda
toyota
#=> ["ford", "chevy", "honda", "toyota"]
irb> car
NameError: undefined local variable or method `car` for #<Object:0x399770 @cars=["ford", "chevy", "honda", "toyota"]>
        from (irb):3
        from /usr/local/bin/irb:12:in `<main>`
irb> for car in @cars
     puts car.reverse
     end
drof
yvehc
adnoh
atoyot
#=> ["ford", "chevy", "honda", "toyota"]
irb> car
#=> "toyota"

for/in leaves the iterator variable in scope afterwards, while #each doesn't.

Personally, I never use ruby's for/in syntax.

rampion
+1 - That's much better than my answer
DanSingerman
thanks for the quick and great reply! :)
jacob
+1 : that's strange. C# loopvar does not out-live the for construct. Anyways all the more reason to stick to each
Gishu
see also http://stackoverflow.com/questions/155462/what-is-for-in-ruby/155543#155543
rampion
Ruby scoping is pretty bad, the perl equivalent of that will not even compile with strict.
Evan Carroll