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 という 2 つのクラス メソッドが与えられます。
継承されたクラス メソッドは、表示されているモジュールの self.included メソッドと同じように機能します。このモジュールを含むクラスがサブクラス化されるたびに、宣言されたクラス レベルの継承可能なインスタンス変数 (@inheritable_attributes) ごとにクラス レベルのインスタンス変数が設定されます。

于 2012-05-24T00:50:48.717 に答える