During a recent PR review I found myself having to explain why we would want to use each over for/in in Ruby. Turns out most people think it's just more idiomatic to use each over for but it's much more than that.
With for, the variable you use will be available outside of the loop, while the variable you use in each will only be available in that block.
x = [1, 2, 3]
x.each do |i|
puts i
end
#...
puts i #=> NameError: undefined local variable or method `i' for main:Object
for i in x
puts i
end
#...
puts i #=> 3
This is because for does not introduce a new scope but each does via the block you pass it. It’s important to understand scope here because you can really make a mess with for if you’re not careful. ie:
def num
puts 4
end
num #=> 4
x = [1, 2, 3]
x.each do |num|
puts num
end
#...
num #=> 4
for num in x
puts num
end
#...
num #=> 3
I hope this clears up why you should use each over for while working with Ruby. It's a simple thing that can have a rather large impact.
Top comments (3)
I think scope trips up a lot of newish devs -- well, also some of us vets if we're not keeping it in mind. It is good to use methods that mean it doesn't even come into play!
how am i getting different results than you @drbragg ?
What's returned if you call
numafter theeachblockand after thefor` block?