opening an eigenclass does not change the class variable definition context
module Mod1 class << Object.new C = 1 @@cv = 1 p Module.nesting, constants(false), class_variables(false), Mod1.class_variables(false) end end
[#<Class:#<Object:0xb6913d98>>, Mod1] [:C]  [:@@cv]
Shouldn't class var resolution be relative to the current lexical class (Module.nexting.first)?
Updated by jeremyevans0 (Jeremy Evans) over 1 year ago
This issue is not specific to opening a singleton class (
class <<), but applies to any case where the class being opened is a singleton class. You get the same output for:
module Mod1 O = Object.new.singleton_class class O C = 1 @@cv = 1 p Module.nesting, constants(false), class_variables(false), Mod1.class_variables(false) end end
This explains why it works for
nil (and presumably
module Mod1 class << nil C = 1 @@cv = 1 p Module.nesting, constants(false), class_variables(false), Mod1.class_variables(false) end end # [NilClass, Mod1] # [:C] # [:@@cv] # 
I'm not sure if this class variable behavior is a bug or spec. If you consider it a bug, and say that class variables set inside a singleton class definition are set on the singleton class and not the outer nesting, then you would probably break the following code (and I'm guessing
class << self is much more common than
class << some_other_object):
module Mod1 class << self @@cv = 1 end def a @@cv end end
FWIW, Ruby does allow you to set class variables on singleton classes via
class_variable_set, but you cannot access them via normal means:
module Mod1 singleton_class.class_variable_set(:@@cv, 1) class << self p class_variable_get(:@@cv) @@cv end end # 1 # NameError: uninitialized class variable @@cv in Mod1
Updated by jeremyevans0 (Jeremy Evans) about 1 year ago
- Assignee set to matz (Yukihiro Matsumoto)
- Status changed from Feedback to Assigned
Class variable lookup going from singleton class to actual class appears to be intentional behavior if you look at the code. The
class_variable_get bug is being addressed in #8297. Assigning to matz for confirmation that this behavior is expected.
Please do not set the status to Feedback if you have responded. Feedback status means that committers are waiting for feedback from you. You can reset the status to Open if you disagree with the initial closing of an issue.