简体   繁体   English

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

[英]Class accessors and inheritance in Ruby on Rails

Like the following code shows, having class accessors defined in the superclass could have unexpected behaviours because the class accessor is the same variable for all the subclasses. 如下面的代码所示,在超类中定义类访问器可能会有意外行为,因为类访问器对于所有子类都是相同的变量。

class Super 
  cattr_accessor :name
end

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

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

SubA.name
 => "B" # unexpected!

I want to have an independent class accessor for each subclass, so a possible solution is moving the cattr_accessor from the superclass and putting it in every subclass. 我希望每个子类都有一个独立的类访问器,因此可能的解决方案是将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!

It is this solution a good practice? 这个解决方案是一个很好的做法吗? Do you know better alternatives? 你知道更好的选择吗?

Open up Super 's singleton class and give that a regular attr_accessor : 打开Super的单例类并给它一个常规的attr_accessor

class Super 
  class << self
    attr_accessor :name
  end
end

That should give you the semantics you want: a "class level instance variable". 这应该给你你想要的语义:“类级实例变量”。

However I'll note that any value set for :name on Super will not be inherited by Super 's children. 但是我会注意到,为Super :name设置的任何值都不会被Super的孩子继承。 This makes sense if you think about it: the children inherit the attr_accessor , not the attribute itself. 如果你仔细想想,这是有道理的:孩子们继承了attr_accessor ,而不是属性本身。

There are some ways around this, most notably rails provides class_attribute which provides the ability of children to inherit the value of the parent's attribute unless explicitly overridden. 有一些方法可以解决这个问题,最值得注意的是rails提供了class_attribute ,它提供了子节点继承父属性值的能力,除非明确地重写。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM