web-dev-qa-db-ja.com

Rubyのattr_accessorは、インスタンス変数の代わりにクラス変数またはクラスインスタンス変数をどのように生成できますか?

attr_accessor、デフォルトでは、対応するゲッターとセッターと共にインスタンス変数を作成します。しかし、インスタンス変数を作成する代わりに、クラス変数またはクラスインスタンス変数を作成する方法はありますか?

29
pez_dispenser

このような:

class TYourClass
  class << self
    attr_accessor :class_instance_variable
  end
end

これは、クラス(クラス自体がインスタンスである)のメタクラスを開き、それに属性を追加すると見なすことができます。

attr_accessorはクラスClassのメソッドです。クラスに2つのメソッドを追加します。1つはインスタンス変数を読み取り、もう1つはインスタンス変数を設定します。可能な実装は次のとおりです。

class Class
  def my_attr_accessor(name)
    define_method name do
      instance_variable_get "@#{name}"
    end 
    define_method "#{name}=" do |new_val|
      instance_variable_set "@#{name}", new_val
    end
  end
end

完全にテストされていないクラス属性アクセサー:

class Class
  def class_attr_accessor(name)
    define_method name do
      class_variable_get "@@#{name}"
    end 
    define_method "#{name}=" do |new_val|
      class_variable_set "@@#{name}", new_val
    end
  end
end
46
krusty.ar

Railsでは(またはrequire 'active_support'を実行するすべての場所で)cattr_accessor :nameを使用して、真のクラス変数アクセサーを取得できます。

他の人が指摘したクラスインスタンス変数は、通常はより便利です。 APIdock cattr_accessor page には、どちらを必要としないかを明確にするいくつかの役立つ議論と、cattr_accessorcattr_reader、およびcattr_writer関数のソースがあります。

20
Charles Dale