ara.t.howard said:
cfp:~ > cat a.rb
class A; @@aa = 42;end
A.class_eval{ define_method

foo){ A.send :class_variable_get, '@@aa' } }
p A.new.foo #=> 42
A.send

define_method, :foo){ A.send :class_variable_get, '@@aa' }
p A.new.foo #=> 42
@@aa = 'this is what is meant by closure'
A.send

define_method, :foo){ @@aa }
p A.new.foo #=> ??
cfp:~ > ruby a.rb
42
42
"this is what is meant by closure"
blocks form closures, which is what makes them useful, when you are
defining methods via blocks you need to consider the enclosing scope as
it will be the *primary* namespace lookup. understanding closures is
step one to metaprogramming bliss.
Careful. Putting @@aa at the top level makes it into a kind of global,
so there's no need for a closure to access it:
class A; end
@@aa = 'this is sorta global'
A.class_eval{ define_method

foo){
A.send :class_variable_get, '@@aa' } }
p A.new.foo # ==> "this is sorta global"
p Object.send

class_variable_get, "@@aa")
# ==> "this is sorta global"
It's global in the sense that @@aa is defined at the root of the class
tree (Object), and class var lookup wanders along this tree towards the
root, until it finds a class with @@aa defined.
An example that works _only_ because class vars are affected by closures:
class A; @@bb = 3 end
class B
@@bb = "belongs to B, yet visible in closure"
A.send

define_method, :bar){ @@bb }
end
p A.new.bar
# ==> "belongs to B, yet visible in closure"
begin
p Object.send

class_variable_get, "@@bb")
rescue => ex
puts ex
# ==> uninitialized class variable @@bb in Object
end
p A.send

class_variable_get, "@@bb") # ==> 3
(Note that the @bb=3 is hidden when inside the scope of class B...end.)
But note that the behavior of instance vars in closures is different:
the lookup rules for @foo are dynamic, based on which object is the self
when the code is executed.
class A; end
@@aa = 'this is what is meant by closure'
@a = "bar"
A.send

define_method, :foo){ @@aa }
A.send

define_method, :bar){ @a }
p A.new.foo # ==> "this is what is meant by closure"
p A.new.bar # ==> nil
It is a good idea to avoid class vars, for the following reason:
class A
@@one_by_this_name = 42
end
class B < A
@@one_by_this_name = 43
@@two_by_this_name = "zap"
end
class A
@@two_by_this_name = "pow"
end
class A
p @@one_by_this_name # == > 43 <-- surprise!
p @@two_by_this_name # == > "pow"
end
class B
p @@one_by_this_name # == > 43
p @@two_by_this_name # == > "zap"
end
The order of assignment determines whether a class and subclass share
the class variable!