Ruby Ruby 的类变量 (修正版)

zputee · 2013年05月05日 · 最后由 spike76 回复于 2018年05月06日 · 4628 次阅读

昨天和@zgm 等等的讨论,收益良多,感谢

昨天关于类变量的帖子,写的比较匆忙,论证不严谨,更主要水平有限,所以重新写了一篇。本文从类变量读写的角度,更清晰一些。

一、类变量的赋值 在本类的 ancestors,反向查找。(即 Ojbect 中的类变量最优先----从 Object 类开始查找) --> 找到,直接赋值 --> 找不到,在本类上创建类变量。

二、类变量的读取 在本类的 ancestors,反向查找。 --> 在父类中找到:返回父类中的类变量。(如果本类的有同名的类变量,同时被删除。) --> 在本类中找到:返回本类中的类变量。

--> 找不到:报错。

三、singleton 方法定义其他类中时,在外层类中查找(方法同以上)。


一、类变量的赋值

@@v = 100
Object.class_variables 

#1.在本类的ancestors,反向查找,父类Object有@@v
class C
  @@v = 90   #向父类中的@@v赋值。
end
@@v       #=>90
C.class_variables  #=>[]
Object.class_variables #[:@@v]

#2.反向查找,父类中无@@v1,
class C
  @@v1 = 80  #在C中创建类变量@@v1
end
C.class_variables   #=>[:@@v1]
Object.class_variables  #=[:@@v] 

二、类变量的读取

@@w  = 111
Object.class_variables #[:@@w]

#1.反向查找,在父类Object中找到了
class C
  p @@w    #=>111 ,返回父类中的@@w
end
C.class_variables  #=>类C中无@@W

#----------------------------------------------------
#准备工作
class C
  @@w2 = 222        #新定义C类变量
end
@@w2 = 333          #在Object上,定义@@w2 
Object.class_variables  #=>Object中有@@w2
C.class_variables   #=>C中有@@W2
#现在父类Object和C类中都有@@w2

#2.开始读类变量。反向查找,在父类Object中找到了
C.class_variable_get :@@w2  #=>333  #读出Object中@@w2,  删除本类中的@ww2  
C.class_variables   #=>[]   #C中已经无@@w2
Object.class_variables  #=>Object有@@w2

三、singleton 方法定义其他类中时,在外层类查找。

#与外层不同类的single方法中,在外层类中查找!!
class A; @@v = "A"; end
class B; @@v = "B"; end
class C < A; end
 #B中有@@V, 类C的父类A 中也有@@v
class B     
  def C.v    
    @@v    #读方法外层类B中的@@v
   end       
end
C.v   #=>B

赞。不过楼主应该把 ruby 的版本写出来。 在 ruby2.4.1 的版本中,class_variables 方法默认会把继承链上的类变量输出,例子中现在应该给 class_variables 加上 false 参数咯

zputee Ruby 的类变量 提及了此话题。 04月03日 10:56
需要 登录 后方可回复, 如果你还没有账号请 注册新账号