20

我希望一个子类从其父类继承一个类级实例变量,但我似乎无法弄清楚。基本上我正在寻找这样的功能:

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, 2, 3]

> Beta.bar
# [1, 2, 3, 4]

> Delta.bar
# [1, 2, 3, 5]

> Gamma.bar
# [1, 2, 3, 4, 'a']

显然,这段代码不起作用。基本上我想为父类中的类级实例变量定义一个默认值,它的子类继承。子类的更改将成为子类的默认值。我希望这一切都发生,而不会改变一个类的值来影响其父级或兄弟级。Class_inheritable_accessor 给出了我想要的行为......但是对于一个类变量。

我觉得我可能要求太多了。有任何想法吗?

4

3 回答 3

12

Rails 将其作为一个名为class_attribute的方法内置到框架中。您可以随时查看该方法的源代码并制作自己的版本或逐字复制。唯一需要注意的是,您不要更改原地的可变项

于 2012-05-24T00:18:18.573 回答
10

我在我的项目中使用 resque 所做的是定义一个基础

class ResqueBase
  def self.inherited base
    base.instance_variable_set(:@queue, :queuename)
  end
end

在其他子作业中,将默认设置队列实例。希望它可以提供帮助。

于 2012-11-12T23:28:18.140 回答
6

使用混合:

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)设置一个类级别实例变量。

于 2012-05-24T00:50:48.717 回答