Assume a simple ruby program using a class variable,
class Holder
@@var = 99
def Holder.var=(val)
@@var = val
end
def var
@@var
end
end
@@var = "top level variable"
a = Holder.new
puts a.var
I guess the result should be 99
, but the output is not 99
. I wonder why. Since class variable's scope is the class, I assume the line @@var = "top level variable"
would not affect the variable in the class.
@@var
is a class variable of Holder
. And the @@var
at the top level is not the same class variable of same name @@var
of Holder
, it is you are creating a brand new class variable for the class Object
. Now @@var
is shared with the subclass(es) of the parent class. Object
is a parent class of the class Holder
. In Ruby, if you don't explicitly define a super class of any custom class, you are defining using class
keyword, then Object
class becomes the default super class of the class, you just created.
On top level, you are defining a new class variable in the class Object
, like you did, in your posted example. As through inheritance, it is now available to the class Holder
.
I mean, when you wrote the below :
class Holder
@@var = 99
def Holder.var=(val)
@@var = val
end
def var
@@var
end
end
@@var
is not added already to the Object
class. Now on the top-level when you wrote the below line :
@@var = "top level variable"
It means, you are adding it to Object
class and also updating old variable(@@var
) same name as in the Holder
class one, with this new one, you just defined in the scope of Object
class.
Remember, class variables are shared variables and visible only to the class(B
), where you defined it and its descendant class(C
), descendant(D
) of the descendant class(C
), so on. But not visible by the super-class( A
as below ) of the class( B
as below ), until you defined a same name variable in the parent class(A
), as you are having in the child class(B
).
class A
end
class B < A
@@var = 10
end
class C < B
end
class D < C
end
A.class_variable_get(:@@var) # uninitialized class variable @@var in A (NameError)
B.class_variable_get(:@@var) # 10
C.class_variable_get(:@@var) # 10
D.class_variable_get(:@@var) # 10