Ruby Ruby Loops Ruby Iteration For Loops

Sam Fitz
Sam Fitz
7,036 Points

The Distinction Between For Loops and Other Kinds of Loops

Near the end of this video (2:55), Jason says that the variables for For Loops exist outside of the loop, but for Other types of Loops the variables exist only inside the loop.

Can someone please clarify his meaning here? It seems to be a significant point, but I feel I don't understand. The videos and challenges I've completed up to this point demonstrate that "Loop ", "While", "Each", and "If" loops all can use variables outside of the statement of loop itself.

6 Answers

Maciej Czuchnowski
Maciej Czuchnowski
36,426 Points

That is an interesting concept. So here is an example of an .each loop (they are preferred in Ruby and Rails):

[1, 2, 3, 4, 5].each do |a|
  # do something here
end

puts a

This code will fail and the error will say "undefined local variable or method 'a' for main:Object (NameError)". Why? Because variable a was created inside the loop and only exists between its do and end keywords. Outside that scope it does not exist in this particular example. You may define variable a before the loop and then there will be no error. Example:

a = 0

[1, 2, 3, 4, 5].each do |a|
  # do something here
end

puts a

Now this would print 0 on the screen. Why? Because a exists outside the loop and has value 0. Inside the loop it is shadowed by a temporary local variable of the same name. Once the loop ends, the only available variable a is the one that had the value 0.

But the for loop has a different behavior. If you take this code:

for a in 1..5
  # do something here
end

puts a

You might expect this to cause the same error as before, since this is almost the exact same code as the first snippet. But it prints out 5 without any errors or warnings. That is because the a variable, although it was created inside the loop and should be local for it, exists outside this scope between do and end. And if you had the variable a defined before like this:

i = 0

for i in 1..5
  # do something here
end

puts i

This will print 5, not 0 like in the second example. That is because shadowing did not take place - the for loop was operating on an existing variable, did not create its own local loop to work with.

This is why Ruby programmers tend to avoid using the for loop in favor of each loop unless they want this very behavior.

Excellent explanation. I'm glad I read this first before watching.

Gavin Ralston
Gavin Ralston
28,765 Points

Ruby is super fun, but the way for loop variables work is...gross.

I'm very happy this question was asked and answered. Thanks for the thorough explanation!

Jitli Gan
Jitli Gan
2,667 Points

You did a much better job explaining this than Jason. Cheers!

lindseyk
lindseyk
4,506 Points

Oh, thank you! I was confused about this as well!

Thank you for the examples, that was very helpful!

Theo VOGLIMACCI
Theo VOGLIMACCI
8,027 Points
5.each do        
puts "Thanks !" 
end