Michael MacDonald

Variables, Scope and Iterators

In Ruby on September 30, 2009 at 8:00 am

When I first starting using Ruby I used the for loop to iterate over arrays. A colleague recommended I use the each iterator instead. Why? Check this out…

baby_names = [ "Gilbert", "Dougal", "Digby", "Angus", "Rory" ]

baby_names.each { |name|
  name
}

puts name
=> NameError: undefined local variable or method 'name'

So far so good. That’s what I would expect. Now, let’s try it using a for loop.

for name in baby_names
  puts name
end

puts name
=> "Rory"

Oh dear! The variable name persists outside of the scope of the for loop. That’s not what I expected but I suppose it makes sense since you are setting the variable at the start of each loop. Compare to this the each iterator where the variable is assigned inside the block for each iteration. Still, to avoid nasty surprises later on, use the each method instead.

But wait! The each block isn’t perfect either. If the block variable has already been defined previously then it’ll overwrite the existing value. In other words, the variable is not locally scoped to the block (which is what I would’ve expected).

name = "Lachlan"

baby_names.each { |name|
  name
}

puts name
=> "Rory"

This also occurs with the for loop as well. You just can’t trust ruby! 😉

name = "Lachlan"

for name in baby_names
  puts name
end

puts name
=> "Rory"

So the moral of the story is simply be careful with your variables and minimise the reuse of variable names just in case there is some funny business going on. I believe it all has something to do with closures but I don’t understand it. If you do, please leave a comment!

See also:

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: