(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