Ruby类实例variables与类variables

我读过“ 什么时候Ruby实例variables被设置? ”,但我有两个使用类实例variables的想法。

类variables由类的所有对象共享,实例variables属于一个对象。 如果我们有类variables,那么没有太多空间可以使用类实例variables。

有人可以解释这两者之间的差异,何时使用它们?

这是一个代码示例:

class S @@k = 23 @s = 15 def self.s @s end def self.k @@k end end p Ss #15 p Sk #23 

我现在明白,类实例variables不会沿着inheritance链传递!

类上的实例variables:

 class Parent @things = [] def self.things @things end def things self.class.things end end class Child < Parent @things = [] end Parent.things << :car Child.things << :doll mom = Parent.new dad = Parent.new p Parent.things #=> [:car] p Child.things #=> [:doll] p mom.things #=> [:car] p dad.things #=> [:car] 

类variables:

 class Parent @@things = [] def self.things @@things end def things @@things end end class Child < Parent end Parent.things << :car Child.things << :doll p Parent.things #=> [:car,:doll] p Child.things #=> [:car,:doll] mom = Parent.new dad = Parent.new son1 = Child.new son2 = Child.new daughter = Child.new [ mom, dad, son1, son2, daughter ].each{ |person| p person.things } #=> [:car, :doll] #=> [:car, :doll] #=> [:car, :doll] #=> [:car, :doll] #=> [:car, :doll] 

使用一个类的实例variables(而不是该类的一个实例),你可以存储一些通用的类,而不需要自动获得子类(反之亦然)。 通过类variables,您可以不必从实例对象中编写self.class ,而且(如果需要)还可以在整个类层次结构中自动共享。


将它们合并成一个也包含实例上的实例variables的例子:

 class Parent @@family_things = [] # Shared between class and subclasses @shared_things = [] # Specific to this class def self.family_things @@family_things end def self.shared_things @shared_things end attr_accessor :my_things def initialize @my_things = [] # Just for me end def family_things self.class.family_things end def shared_things self.class.shared_things end end class Child < Parent @shared_things = [] end 

然后在行动:

 mama = Parent.new papa = Parent.new joey = Child.new suzy = Child.new Parent.family_things << :house papa.family_things << :vacuum mama.shared_things << :car papa.shared_things << :blender papa.my_things << :quadcopter joey.my_things << :bike suzy.my_things << :doll joey.shared_things << :puzzle suzy.shared_things << :blocks p Parent.family_things #=> [:house, :vacuum] p Child.family_things #=> [:house, :vacuum] p papa.family_things #=> [:house, :vacuum] p mama.family_things #=> [:house, :vacuum] p joey.family_things #=> [:house, :vacuum] p suzy.family_things #=> [:house, :vacuum] p Parent.shared_things #=> [:car, :blender] p papa.shared_things #=> [:car, :blender] p mama.shared_things #=> [:car, :blender] p Child.shared_things #=> [:puzzle, :blocks] p joey.shared_things #=> [:puzzle, :blocks] p suzy.shared_things #=> [:puzzle, :blocks] p papa.my_things #=> [:quadcopter] p mama.my_things #=> [] p joey.my_things #=> [:bike] p suzy.my_things #=> [:doll] 

我相信主要(唯一?)不同的是inheritance:

 class T < S end p Tk => 23 Sk = 24 p Tk => 24 p Ts => nil 

类variables由所有的“类实例”(即子类)共享,而类实例variables只针对该类。 但是,如果你不打算延长你的课程,那么差别纯粹是学术的。

#class实例variables只能用于类方法,而不能用于实例方法,而类variables可用于实例方法和类方法。 此外,类实例variables在inheritance链中丢失,而类variables不是。

 class Vars @class_ins_var = "class instance variable value" #class instance variable @@class_var = "class variable value" #class variable def self.class_method puts @class_ins_var puts @@class_var end def instance_method puts @class_ins_var puts @@class_var end end Vars.class_method puts "see the difference" obj = Vars.new obj.instance_method class VarsChild < Vars end VarsChild.class_method 

正如其他人所说,类variables是在给定的类和它的子类之间共享的。 类实例variables只属于一个类; 它的子类是分开的。

为什么这种行为存在? 那么,Ruby中的所有东西都是一个对象 – 甚至是类。 这意味着每个类都有一个对应于它的类Class (或者说, Class的子Class )的对象。 (当你说class Foo ,你实际上是在声明一个常量Foo并为它分配一个类对象。)每个Ruby对象都可以有实例variables,所以类对象也可以有实例variables。

麻烦的是,类对象上的实例variables实际上并不像你通常希望类variables的行为那样。 您通常希望在超类中定义的类variables与其子类共享,但这不是实例variables的工作方式 – 子类具有自己的类对象,并且该类对象具有自己的实例variables。 所以他们引入了单独的类variables和更可能想要的行为。

换句话说,类实例variables是Rubydevise的一个偶然。 你可能不应该使用它们,除非你明确知道你在找什么。