Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

There is an important reason why one would use #each instead of a for loop: encapsulation.

Looping over a collection object requires some knowledge of its internal state (length in the case of a simple linear structure like Array). In most cases where we use for loops, that information isn't really relevant. There is no need to expose it to the outside world and break encapsulation.

Being consistent in using #each helps when you have complex/custom collection objects where iteration can't be done through a simple for loop. The object might not want to expose its underlying collection and hence can't provide a suitable way to use a for loop on it. Or maybe the collection object has dead elements that it wants to skip and so on. There are any number of reasons to hide the implementation details of the iteration from the external world.

Given this and since Ruby has a powerful block syntax, favouring #each fanatically over for loops, IMHO, is a good thing.

EDIT: I'm also guilty of accusing LRTH with the 'not idiomatic enough' charge in a blogpost I recently wrote for Ruby beginners at http://www.jasimabasheer.com/posts/meta_introduction_to_ruby....



"Looping over a collection object requires some knowledge of its internal state (length in the case of a simple linear structure like Array). In most cases where we use for loops, that information isn't really relevant. There is no need to expose it to the outside world and break encapsulation."

The examples from the article don't make me think I need length or any other internal knowledge to use the for..in loop as opposed to each.


My bad, sorry. The 'for..in' construct does not require you to expose the length of the structure.

However, the other argument still holds true: In case of a user-defined collection object, 'for..in' will not work since the underlying collection will be hidden.


Under the hood, 'for..in' just calls #each. Therefore, it is easy to make 'for..in' work with a custom collection: just define #each. And that is what you would do anyway if you were defining an Enumerable custom collection.


In Ruby "for...in" is just syntactic sugar for #each. Try defining your own #each on a random object!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: