I just had a quick question regarding loops in Ruby. Is there a difference between these two ways of iterating through a collection?
# way 1
@collection.each do |item|
# do whatever
end
# way 2
for item in @collection
# do whatever
end
Just wondering if these are exactly the same or if maybe there's a subtle difference (possibly when @collection
is nil).
I just want to make a specific point about the for in loop in Ruby. It might seem like a construct similar to other languages, but in fact it is an expression like every other looping construct in Ruby. In fact, the for in works with Enumerable objects just as the each iterator.
The collection passed to for in can be any object that has an each iterator method. Arrays and hashes define the each method, and many other Ruby objects do, too. The for/in loop calls the each method of the specified object. As that iterator yields values, the for loop assigns each value (or each set of values) to the specified variable (or variables) and then executes the code in body.
This is a silly example, but illustrates the point that the for in loop works with ANY object that has an each method, just like how the each iterator does:
And now the each iterator:
As you can see, both are responding to the each method which yields values back to the block. As everyone here stated, it is definitely preferable to use the each iterator over the for in loop. I just wanted to drive home the point that there is nothing magical about the for in loop. It is an expression that invokes the each method of a collection and then passes it to its block of code. Hence, it is a very rare case you would need to use for in. Use the each iterator almost always (with the added benefit of block scope).
As far as I know, using blocks instead of in-language control structures is more idiomatic.
See "The Evils of the For Loop" for a good explanation (there's one small difference considering variable scoping).
Using
each
is considered more idiomatic use of Ruby.In 'for' loop, local variable is still lives after each loop. In 'each' loop, local variable refreshes after each loop.
Never ever use
for
it may cause bugs.The difference is subtle but may cause tremendous bugs!
Don't be fooled, this is not about idiomatic code or style issues. This is a matter of avoiding almost untraceable bugs in production code. Ruby's implementation of
for
has a serious flaw and should not be used. Always useeach
loops, never ever usefor
loop.Here is an example where
for
introduces a bug,Prints
Using
%w{foo bar quz}.each { |n| ... }
printsWhy?
In a
for
loop the variablen
is defined once and only and then that one definition is use for all iterations. Hence each blocks refer to the samen
which has a value ofquz
by the time the loop ends. Bug!In an
each
loop a fresh variablen
is defined for each iteration, for example above the variablen
is defined three separate times. Hence each block refer to a separaten
with the correct values.One more different..
source: http://paulphilippov.com/articles/enumerable-each-vs-for-loops-in-ruby
for more clear: http://www.ruby-forum.com/topic/179264#784884