【Ruby v2.6】インスタンス変数
前置き
インスタンス変数とは
書き方
クラス定義内で、文字列の頭に「@」をつけて表します。「クラスインスタンス変数」と同じ書き方なので注意が必要です。
生成
インスタンス変数は、インスタンスメソッド内で@付きの文字列に、何かオブジェクトを代入したタイミングで生成されます。 他の場所(メソッドの外や、クラスメソッド内)で @付きの文字列に代入した場合は、「クラスインスタンス変数」と解釈されます。
インスタンス変数は、インスタンス毎に保持されます。このため、同じクラスから別々のインスタンスを生成しても、インスタンス変数は共有されません。
下記、サンプルクラスです。
class A # attr_accessor は、ゲッター、セッターのメソッドのみを生成する。 # なので、この宣言だけではインスタンス変数はまだ生成されません。 attr_accessor :insval_c # インスタンス初期化用 インスタンスメソッド def initialize # このメソッドは、インスタンスを生成したタイミングで実行されるので、 # インスタンス生成と同時にインスタンス変数も生成されます。 @insval_a = "@insval_a" end # 通常のインスタンスメソッド def a_method # このインスタンス変数は、a_method メソッドを実行したら生成されます。 @insval_b = "@insval_b" end end
@insval_a
は、インスタンスメソッド initialize
で代入されています。initialize
メソッドは、インスタンス生成時に実行されるので、 インスタンス生成と同じタイミングで生成されます。
@insval_b
は、別のメソッド a_method
内で代入されているので、インスタンス生成時にはまだ生成されていません。a_method
メソッドが実行されたタイミングで、初めて生成されます。
@insval_c
は、attr_accessor
として定義されていますが、attr_accessor
は、ゲッターメソッド、セッターメソッドを定義するだけなので、実行はされません。ですので、この宣言だけでは@insval_c
は生成されず、セッターで値を代入しないと生成されません。
irb 等でクラスを読み込んで確認すると、下記のようになります。
obj1 = A.new # インスタンス obj1 を生成 obj1.instance_variables # => [:@insval_a] obj1.a_method # a_method メソッドを実行すると・・・ obj1.instance_variables # => [:@insval_a, :@insval_b] obj1.insval_c # => nil obj1.insval_c = "@insval_c" # insval_c は値をセットして始めて生成される obj1.instance_variables # => [:@insval_a, :@insval_b, :@insval_c] obj2 = A.new # 別のインスタンス obj2 を生成 obj2.instance_variables # => [:@insval_a] # obj1 の変数とは共有されない
まとめ
- インスタンス変数は、インスタンス毎に値を保持します。
- インスタンス変数は、@付きの文字列に何かしらのオブジェクトを代入することで生成されます。
- インスタンス変数として生成する場合は、必ずインスタンスメソッド内で代入しないといけません。ただし、インスタンスメソッド内ならどこでもOKです。