使用 `class_attribute` 和 `Hash` 的正确方式是什么?

7
Rails有一个类扩展叫做class_attribute,它允许类实例变量的继承。这对于不可变对象(例如String)有效,但对于可变对象无效。
class Base
  class_attribute :options
  self.options = {}
end

class SubClass < Base
end

Base.options                   # {}
SubClass.options[:foo] = "bar" # { foo: "bar" }
Base.options                   # { foo: "bar" }

问题是如何让子类拥有自己的 options 副本,而不需要在其主体中显式初始化它:
class SubClass < Base
  self.options = {}
end
1个回答

6
诀窍在于在父类中使用 inherited 方法:
class Base
  class_attribute :options
  self.options = {}

  class << self
    def inherited(subClass)
      subClass.options = self.options.clone
    end
  end
end

每次子类化时,这将自动克隆父级的选项。

1
非常好的技巧,节省了我很多时间 - 但是由于inherited钩子中存在一些拼写错误/变量命名不正确/接收器错误等问题,所以给出的代码示例无法正常工作:应该将self._options = self._options.clone替换为subClass.options = self.options.clone... - Mayinx
这个答案也帮了我很多,但是你需要在inherited方法的末尾包含super,否则你会遇到错误(在我的情况下是undefined method 'synchronize' for nil:NilClass)。如果可以,请更新答案。 - baka-san

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接