(Question already posted at Ruby Forum, but did not evoke any answer there).
This is my code:
class MC
def initialize
@x = 5
@@y = 6
end
def f
puts @x
puts @@y
end
end
m = MC.new
m.f
m.f produces the expected output without an error:
5
6
But this:
def m.g
puts @x
puts @@y
end
m.g
produces:
5
warning: class variable access from toplevel
NameError: uninitialized class variable @@y in Object
Why can I access @@y from f, but not from g?
Mentioning of toplevel and Object in the warning and the error message is puzzling to me.
@x is printed as 5, so its environment is MC. This excludes the possibility that @x and @@y in the definition of m.g refer to the toplevel environment (Object) instead of MC.
Why did I get the error message?
All variants below work:
def m.g; puts self.class.send(:class_eval, '@@y') end
def m.g; puts self.class.class_variable_get(:@@y) end
class << m; def g; puts self.class.send(:class_eval, '@@y') end end
class << m; puts class_variable_get(:@@y) end
But these fail:
def m.g; puts @@y; end
class << m; puts class_eval('@@y') end
I would consider this being a ruby parser glitch.
You do not create g in the class MC but in m's singleton class (a.k.a. eigenclass).
This is a class existing specifically for the object m to store the singleton methods that are defined just for m.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With