Stop using the for loop 10
As a longtime C++ and C# developer I have a lot of coding traditions that I don’t realize I have until I’m in the middle of writing some code in, say, a controller action, and I have to think, Oh God, how do I do this in Ruby? I know how I would do it in C# – but how do I do this in Ruby?
One example that really started to break the ice for me and get me on the Ruby train is Ruby’s answer to the typical “for” loop. You know, it goes something like this in C#:
for (int i=0; i < total; ++i)
{
// do something here
}
And once upon a time I used to get confused about how to write the ending condition. Is it i < total or i <= total? And so on.
Well, fellow C++/C# softies that are now on Rails, heed this advice: STOP WRITING FOR LOOPS. Yes, you heard me. Stop it right now. There are better ways in Ruby to loop over some code. Let’s look at the most common ways.
A great one to start learning is times. When you just want to repeat something a given number of times, well, just do so:
10.times { puts "hockey" }
will print “hockey” ten times.
But wait, it gets better. Suppose you want to know which iteration you’re on. You can either do this:
10.times { |n| puts n }
which will print the numbers 0 through 9, or mayabe you want to do this:
5.upto(9) { |n| puts n }
which will print the numbers 5 through 9, inclusive. Write the equivalent C++ code and tell me which is easier to read, hmmm?
Ok, so now for something you’re likely to do quite a bit in your actions and views. Suppose you have an array and want to loop over the values in the array. In C#, it’s like this:
foreach (Object obj in myList)
{
// do something with obj
}
In Ruby, do this:
myList.each do |obj| # do something with obj end
or, if you just can’t wean yourself from that three-letter keyword, Ruby does provide a syntactical sugar alternative:
for obj in myList do # do something with obj end
So there you have it, lots and lots of ways to loop over stuff in Ruby that’s more intuitive and flexible than what we used to do in that other language.



Gonna have to give it a try :(
And what am I supposed to do in a case like this?
for(int i = 0; i < arr.Length; ++i) arr[i] = 3*i;
that is, I don't want just to iterate over the values in the array, but to modify them instead.
In other words, you told us how to know at which position of an iteration we are with the .times method. But how can we know at which position of an iteration we are in the .each iterator, or the "for obj in arr do" loop?
Hi Ernesto. Good question, with an easy answer. Just use .each_with_index instead of .each, like this:
arr.each_with_index do |obj, i| obj = 3*i end
each_with_index will provide you with two parameters, the object and the index for the current iteration.
For a quick reference to everything the Enumerable module offers, check out http://ruby-doc.org/core/classes/Enumerable.html. (The Array class "mixes in" the Enumerable module, that's why arrays have .each_with_index).
Make sense? Let me know.
Jeff
For anyone reading this from a Google search, Enumerable#collect was made for the scenario Ernesto describes.
[1, 2, 3].collect{|x| x * 3} => [3, 6, 9]
Simple as pie and as yummy too! Enumerable has a lot of really useful methods and I encourage new Rubyists to check them all out.
RSL, I think Ernesto was wanting to modify the array in place, which collect won't do, so that's why I pointed him to
each_with_index.But you're right that
.mapand.collectare not appreciated as much as they should be, so thanks for pointing that out.<% Dir.glob('*').each do |i| %>-
<%= i%>
<% end %>
delete other version. keep this one.
I spent 1/2 hr today to debug a stupid for loop in rails today. I am a beginner at rails and I was trying to figure out how to do a for loop with an array and I had most of the code right except... lets see if you can figure it out (heehee):
<% Dir.glob('*').each do |i| %>-
<%= i%>
<% end %>
The manifold (and it must not be supposed that this is true) has lying before it the paralogisms of pure reason; however, the discipline of natural reason can thereby determine in its totality, in accordance with the principles of the paralogisms, the things in themselves.
Natural causes have nothing to do with, even as this relates to the employment of natural causes, philosophy; on the other hand, the Antinomies can be treated like the employment of our a priori concepts.
hey !! its very reasonable article. Good post. realy good post
thank you ;)