【问题标题】:Class accessors and inheritance in Ruby on RailsRuby on Rails 中的类访问器和继承
【发布时间】:2014-03-15 09:30:29
【问题描述】:

如以下代码所示,在超类中定义类访问器可能会产生意外行为,因为类访问器对于所有子类来说都是同一个变量。

class Super 
  cattr_accessor :name
end

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

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

SubA.name
 => "B" # unexpected!

我希望每个子类都有一个独立的类访问器,因此一个可能的解决方案是将 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!

这个解决方案是一个好习惯吗?你知道更好的选择吗?

【问题讨论】:

  • 这是预期行为。一个是Super 的属性,由它的子代继承。另一个是子类的一个属性,它覆盖了继承的值。 --- 一个问题,寿:这个值会改变吗?类变量往往是错误的解决方案,考虑它应该是一个常量,还是一个实例变量。

标签: ruby-on-rails ruby inheritance class-variables


【解决方案1】:

打开Super 的单例类并给它一个普通的attr_accessor

class Super 
  class << self
    attr_accessor :name
  end
end

这应该会给你你想要的语义:“类级实例变量”。

但是我会注意到,Super 上为 :name 设置的任何值都不会被 Super 的子代继承。如果您考虑一下,这是有道理的:孩子继承attr_accessor,而不是属性本身。

有一些方法可以解决这个问题,最值得注意的是 rails 提供了class_attribute,它提供了子级继承父级属性值的能力,除非显式覆盖。

【讨论】:

  • 谢谢。我认为 class_attribute 是解决这种情况的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多