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| m * 2 }

puts m.class.to_s
Intuitively, this should output this:
However it outputs this:
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...


Mathieu Martin said...

This will be fixed in Ruby 1.9

It's mentioned in passing in Raganwald's

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.