Sep 30, 2008

Ruby Scoping Gotcha

One little thing you may need to remember when coding in Ruby. Consider this little program:
myArr2D = [ [2, 2], [2, 2] ]

myArr2D.each do |m|
x = m.map { |m| m * 2 }

puts m.class.to_s
end
Intuitively, this should output this:
Array
Array
However it outputs this:
Fixnum
Fixnum
What happens here is that the variable m in the map block overshadows the outer variable m, so that whenever you access the variable m after the call to map, you're accessing the inner variable. This might lead to some unexpected side effects, so make sure you keep it in mind...

2 comments:

Mathieu Martin said...

This will be fixed in Ruby 1.9

It's mentioned in passing in Raganwald's
Thrush

Here's the quote (where x is a variable like your m):
"Ruby 1.9 changes the game. In Ruby 1.8, x is local to the surrounding method (...) But in Ruby 1.9, x is a block local variable, meaning that it does not clobber an existing variable."

Rob Britton said...

Nice. That's the way it should be, in my opinion.

I haven't been reading Raganwald as much nowadays, since Google Reader seems to have trouble with his blog and for some reason if I have to go outside of Google Reader in order to read an entry I tend to procrastinate on it.