Dynamically added instance method cannot access class variable

(The question has already been posted on the Ruby Forum , but did not raise 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 mf 

mf displays the expected result without errors:

 5 6 

But this:

 def mg puts @x puts @@y end mg 

gives:

 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 toplevel and Object in warning and error messages puzzles me.

@x prints as 5 , so its environment is MC . This eliminates the possibility that @x and @@y in the definition of mg belong to the top-level environment ( Object ) instead of MC .

Why did I receive an error message?

+6
source share
2 answers

All options below work:

 def mg; puts self.class.send(:class_eval, '@@y') end def mg; 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 errors:

 def mg; puts @@y; end class << m; puts class_eval('@@y') end 

I would think that this is a ruby ​​analyzer crash.

+5
source

You are not creating g in class MC , but in class m singleton (aka eigenclass).

This is a class that exists specifically for the m object to store singleton methods that are defined only for m .

+4
source

All Articles