クラスレベルのインスタンス変数

最近、このトピックに関する多くの出版物がありますが、初心者には何度も質問があります。 クラスの本体で宣言されたインスタンス変数が期待どおりに機能しない理由の説明のバージョンを公開します。



class User @var = 1 end
      
      







期待される動作



インスタンス変数は、通常の状況から期待どおりに機能します。

 class A def set_a( v ); @a = v; end def get_a; return @a; end end o1 = A.new o1.instance_variables # => [] o1.get_a # => nil o1.set_a 123 o1.instance_variables # => ["@a"] o1.get_a # => 123 o2 = A.new o2.get_a # => nil
      
      







変数は、設定後にインスタンスに表示され、すべてが時計仕掛けのように機能します-インスタンスでのみ表示されます。



デフォルト値



インスタンス変数を使用したサプライズは、通常、デフォルト値を設定する必要があるときに始まります。



 class B attr_accessor :b #  set_b, get_b    @b = 1 end o1 = B.new o1.b # => nil o1.instance_variables # => [] o1.b = 2 o1.b # => 2 o1.instance_variables # => ["@b"]
      
      







おっと。 そして、デフォルト値はどこにありますか? オブジェクトに最初から変数がまったくないのはなぜですか?



このような変数は、 クラスレベルのインスタンス変数と呼ばれます(ロシア語の「クラスレベルのインスタンス変数」ではどうですか?)



クラスはオブジェクトです。





Rubyでは、コードは現在のオブジェクト(クラスのインスタンス)のコンテキストで実行されるため、現在のオブジェクトは常にself疑似変数からアクセスできます。 これらは基本的な真実です。 しかし、どのコンテキスト(オブジェクト)で4行目と2行目が実行されるのかという質問に答えてみてください。



 1: class User 2: @b = 1 3: def a 4: @a = 1 5: end 6: end
      
      







4行目は、予想どおり、User.newで作成したオブジェクトでUserクラスのインスタンスで実行されます。



2行目は、Userクラスを記述するオブジェクト内のClassクラスのインスタンスで実行されます。 このオブジェクトは、Userクラスのインタープリターによる読み取りの直後に作成されます。

Userという単語自体、値がClass型のオブジェクトである定数にすぎません。 このオブジェクトは、Userクラスを記述します。 @b変数はこのオブジェクトを参照します。



 o1 = B.new o1.b # => nil o1.instance_variables # => [] B.instance_variables # => ["@b"]
      
      







実際、彼女はいつもそこにいました。 クラスBおよびクラスBのインスタンスではなく、定数Bに格納されているクラスClassのインスタンス



申込み





クラスレベルのインスタンス変数は何を提供しますか?



これらは、個人クラス変数として機能します。 すべての子孫と同じ名前のインスタンスで使用できる実際のクラス変数とは異なり、変数は宣言されたコンテキストのクラスにのみ属します。



 class B @b = 1 def self.set_b( v ); @b = v; end def self.get_b; @b; end end B.get_b # => 1 B.set_b 2 B.get_b # => 2 class B1 < B; end B1.get_b # => 1 B1.set_b 3 B1.get_b # => 3 B.get_b # => 2
      
      







つまり、そのような変数が宣言されたクラスからの継承ごとに、新しい独立した変数が作成されます。 クラス変数の動作と比較します。



 class C @@c = 1 def self.set_c( v ); @@c = v; end def self.get_c; @@c; end end C.get_c # => 1 C.set_b 2 C.get_b # => 2 class C1 < C; end C1.get_c # => 2 C1.set_c 3 C1.get_c # => 3 C.get_c # => 3 class C2 < C; @@c = 4; end C.get_c # => 4 C1.get_c # => 4 C2.get_c # => 4
      
      







アクセッサ





このような変数は、次のようにアクセサーを使用して作成されます。



 class A class << self attr_accessor :a end #    : self.class.attr_accessor :a #   ,  attr_accessor  private method :( end A.instance_variables # => ["@a"] A.class_variables # => [] Aa # => nil Aa = 123 Aa # => 123
      
      







レールcattr_accessor:aは同じ名前のメソッドを作成し、クラス変数のみを参照することに注意してください。



 class User cattr_accessor :a end User.instance_variables # => [] User.class_variables # => ["@@a"]
      
      







関連資料:





railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby

wiseheartdesign.com/articles/2006/09/22/class-level-instance-variables

snippets.dzone.com/posts/show/4382



読者の皆さん、難しいことではない場合は、ここでトピックに関するリンクを追加して、この資料をトピックに関する教育資料として使用してください。



All Articles