Tuesday, January 18, 2011

Scoping and Closure in Ruby 1.8


The other day, I had to wrote code in this form:
class_eval do
[:foo, :bar].each do |a|
_cache = :"@#{a}_cache"
define_method a do
_cache
end
end
end
I had to ask myself: does this really do what I expect? I know the define_method closes over the _cache variable, but is it really isolated in each iteration? Am I really referencing a different _cache on each iteration? I tried this in the Rails console:
=> [:foo, :bar]
irb(main):009:0> foo
=> :@foo_cache
irb(main):010:0> bar
=> :@bar_cache
Should this have been surprising? I suppose not.