I have the following:
class Test
@@a = 10
def show_a()
puts "a: #{@@a}"
end
class << self
@@b = '40'
def show_b
puts "b: #{@@b}"
end
end
end
Why does following work:
Test.instance_eval{show_b}
b: 40
=> nil
But I can't access @@b
directly?
Test.instance_eval{ @@b }
NameError: uninitialized class variable @@b in Object
Likewise, the following works
t = Test.new
t.instance_eval{show_a}
a: 10
=> nil
but the following fails
t.instance_eval{ @@a }
NameError: uninitialized class variable @@a in Object
I don't understand why I can't access the Class Variables directly from the instance_eval
blocks.
I just asked the same question to Matz during the RubyKaigi party. I was half-drunk, but he was perfectly sober, so you can take this as the definitive answer.
Anton is right - the reason why you cannot access class variables through instance_eval() is "just because". Even class_eval() shares the same issue (Matz himself wasn't totally sure about class_eval() until I told him I'd already tried it). More specifically: scope-wise, class variables are more like constants than instance variables, so switching self (as instance_eval() and class_eval() do) is not going to make any difference when it comes to accessing them.
In general, it might be a good idea to avoid class variables altogether.