我想要一个子类从其父代继承一个类级别的实例变量,但我似乎无法弄清楚.基本上我正在寻找这样的功能:
class Alpha class_instance_inheritable_accessor :foo # @foo = [1,2,3] end class Beta < Alpha @foo << 4 def self.bar @foo end end class Delta < Alpha @foo << 5 def self.bar @foo end end class Gamma < Beta @foo << 'a' def self.bar @foo end end
然后我想要这样输出:
> Alpha.bar # [1,3] > Beta.bar # [1,3,4] > Delta.bar # [1,5] > Gamma.bar # [1,4,'a']
显然,这段代码不起作用.基本上,我想为父类中的类级别实例变量定义一个默认值,它的子类继承.子类的更改将是子类的默认值.我想要这一切发生,一个班级的价值不会改变影响其父母或兄弟姐妹. Class_inheritable_accessor给出了我想要的行为,但是给一个类变量.
我觉得我可能会问太多.有任何想法吗?
解决方法
使用mixin:
module ClassLevelInheritableAttributes def self.included(base) base.extend(ClassMethods) end module ClassMethods def inheritable_attributes(*args) @inheritable_attributes ||= [:inheritable_attributes] @inheritable_attributes += args args.each do |arg| class_eval %( class << self; attr_accessor :#{arg} end ) end @inheritable_attributes end def inherited(subclass) @inheritable_attributes.each do |inheritable_attribute| instance_var = "@#{inheritable_attribute}" subclass.instance_variable_set(instance_var,instance_variable_get(instance_var)) end end end end
将此模块包含在一个类中,给出了两个类的方法:inheritable_attributes和inherited.继承的类方法与所示模块中的self.included方法相同.每当包含此模块的类被子类化时,它将为每个已声明的类级别的可继承实例变量(@inheritable_attributes)设置一个类级别的实例变量.