将“class_attribute”与“Hash”一起使用的正确方法

Yan*_*oto 7 ruby-on-rails mutable class-variables

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" }
Run Code Online (Sandbox Code Playgroud)

问题是如何让子类拥有自己的副本,options而不在其主体中显式初始化它:

class SubClass < Base
  self.options = {}
end
Run Code Online (Sandbox Code Playgroud)

Yan*_*oto 6

诀窍是使用inherited父类中的方法:

class Base
  class_attribute :options
  self.options = {}

  class << self
    def inherited(subClass)
      subClass.options = self.options.clone
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

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