Ruby on Rails中的类访问器和继承

Raf*_*aez 4 ruby inheritance ruby-on-rails class-variables

如下面的代码所示,在超类中定义类访问器可能会有意外行为,因为类访问器对于所有子类都是相同的变量.

class Super 
  cattr_accessor :name
end

class SubA < Super; end
class SubB < Super; end

SubA.name = "A"
SubB.name = "B"

SubA.name
 => "B" # unexpected!
Run Code Online (Sandbox Code Playgroud)

我希望每个子类都有一个独立的类访问器,因此可能的解决方案是将cattr_accessor从超类中移出并将其放在每个子类中.

class Super; end

class SubA < Super
  cattr_accessor :name
end

class SubB < Super
  cattr_accessor :name
end

SubA.name = "A"
SubB.name = "B"

SubA.name
 => "A" # expected!
Run Code Online (Sandbox Code Playgroud)

这个解决方案是一个很好的做法吗?你知道更好的选择吗?

roi*_*ppi 6

打开Super单身课程并给它一个常规attr_accessor:

class Super 
  class << self
    attr_accessor :name
  end
end
Run Code Online (Sandbox Code Playgroud)

这应该给你你想要的语义:"类级实例变量".

但是我会注意到,为:nameon 设置的任何值Super都不会被Super孩子们继承.如果你考虑它,这是有道理的:孩子继承attr_accessor,而不是属性本身.

有一些方法可以解决这个问题,最明显的是rails提供class_attribute了一些能够让孩子继承父属性值的能力,除非明确覆盖.