From: David Masover Date: 2008-09-21T07:55:50+09:00 Subject: Re: for or each? On Saturday 20 September 2008 16:07:20 tekwiz wrote: > On Sep 20, 3:32 pm, Phlip wrote: > > Phlip wrote: > > > tekwiz wrote: > > > > >> This is what roodi would have me do > > > > >>   (0...str.size).each do |i| > > > It leaves you closer to a refactor to .map or .inject or .select or > > > .reject or .delete_if or .each_index or .each_with_index or ... > > > > It also hints at: > > > >    str.each do |ch| > > So, it's a code-readability issue and not a functional or complexity > issue? These things are not entirely separate -- readable code is more likely to be functional and maintainable. Or, maybe a better way of saying it is, the code should not merely be readable, it should be expressing your intent. Each is far more abstract than for. Take a simple array: a = ['one','two','three'] for i in 0...a.size puts "Give me a #{a[i]}" end That's more prone to not work, as there are more visible moving parts, which means more for you to think about, and more that can go wrong -- you might type the wrong variable name in the a[i], for example, or type 0..a.size instead of 0...a.size. It also doesn't express your intent. You don't really need to know or care where you are in that array, in this particular algorithm. You only need to know which item you're going to print right now. So: ['one','two','three'].each do |x| puts "Give me a #{x}" end Shorter, more readable (to me), quicker to type, and has the added benefit that in the above example, that array falls out of scope as soon as the loop ends, so it can be collected sooner. It also gives you a bit more flexibility. Suppose you're iterating over something that someone passed in -- that means that I have to pass in something that behaves like an array. It needs to have an accurate [] method, probably supporting random access, even if you'll only access it sequentially. It needs to have a length method, etc. Which makes things quite a bit more awkward. What if I'm reading lines from a file? Your way would force me to count every line in the file before I even get started. What if it's a complex computation, like all the primes less than a given number? I have to calculate them all out ahead of time, and either store that array (wasting memory), or recalculate them from the beginning. There's more to it, of course -- you could imagine an each method which runs in parallel threads, and I'm sure someone has written such a thing. None of these will apply to every situation. It's entirely possible it's an internal data structure. Even internal data structures could benefit from some flexibility, but maybe you'll never touch this algorithm again. But then, I don't really see a downside to doing it with 'each', instead of 'for', other than that 'for' is what you're used to.