为什么ruby父类会假定其子类的类变量?

为什么ruby父类会假定其子类的类变量?,ruby,Ruby,鉴于此代码: class Mammal @@class_name = "mammal" def self.class_name @@class_name end end class Dog < Mammal @@class_name = "dog" def self.class_name @@class_name end end Dog.class_name # => dog Mammal.class_name # => dog 类

鉴于此代码:

class Mammal
  @@class_name = "mammal"
  def self.class_name
    @@class_name
  end
end

class Dog < Mammal
  @@class_name = "dog"
  def self.class_name
    @@class_name
  end
end

Dog.class_name
# => dog
Mammal.class_name
# => dog
类哺乳动物
@@class_name=“哺乳动物”
def self.class_名称
@@类名
结束
结束
狗类<哺乳动物
@@class_name=“狗”
def self.class_名称
@@类名
结束
结束
Dog.class_名称
#=>狗
哺乳动物类名
#=>狗

为什么这是ruby的一个特性?类变量的作用域似乎与实例变量的作用域不同。类变量的作用域是否在其整个继承链中共享?若然,原因为何?它们是独立的类,应该有作用域类变量,不是吗?我缺少什么?

类变量在整个类层次结构中共享,它们不是继承的,因此赋值顺序很重要:

class Mammal
  @@class_name = "mammal"
  def self.class_name
    @@class_name
  end
end

class Dog < Mammal
  @@class_name = "dog"
  def self.class_name
    @@class_name
  end
end

class Mammal
  @@class_name = "fish"
end

Dog.class_name # fish
Mammal.class_name # fish
类哺乳动物
@@class_name=“哺乳动物”
def self.class_名称
@@类名
结束
结束
狗类<哺乳动物
@@class_name=“狗”
def self.class_名称
@@类名
结束
结束
哺乳类
@@class_name=“鱼”
结束
狗、类名、鱼
哺乳动物、类名、鱼类
更新

改用类实例变量,类变量比较棘手:

class Mammal
  @class_name = "mammal"
  def self.class_name
    @class_name
  end
end

class Dog < Mammal
  @class_name = "dog"
  def self.class_name
    @class_name
  end
end

Dog.class_name # dog
Mammal.class_name # mammal
类哺乳动物
@class_name=“哺乳动物”
def self.class_名称
@类名
结束
结束
狗类<哺乳动物
@class_name=“狗”
def self.class_名称
@类名
结束
结束
Dog.class_name#Dog
哺乳动物。类名#哺乳动物

为什么在整个类层次结构中共享类变量?为什么它们没有类作用域?@AndrewKim,因为这是类变量的工作方式。你知道为什么这是一个特性吗?似乎类实例变量可能与实际的对象实例变量有冲突,不管是哪种方式,这让我更清楚了@安德鲁·金。不,它们不能有冲突,因为实例变量绑定到
self
,它是当时运行的当前对象。你问了几个相关的问题。其中一个问题是完全重复的,这就是为什么我刚刚使用了所谓的“重复锤”。另一个问题“为什么”不是完全重复的,尽管我怀疑这是一个很难找到答案的问题。在大多数情况下,答案是“这就是它的方式,因为Ruby的作者决定这样做。”如果我们足够幸运地找到Matz写的关于类变量行为的东西,那么“为什么”部分可以回答。类变量不仅在类及其子类之间共享,我还应该补充一点,
@
类变量几乎从来都不是一个好主意。每当我使用过使用它们的代码时,我通常能够将它们更改为类实例变量,这更易于推理。感谢@WayneConrad对重复的内容表示抱歉,这让我感觉很有道理:“将它们视为范围有限的全局变量。”