• ベストアンサー

インスタンス変数とクラス変数の違い

1つのクラスオブジェクト内のインスタンス全てで共有できる クラス変数 @@a と、 同じインスタンス内であればメソッドの定義を越えてその値を 参照したり、変更したりできるインスタンス変数 @a のスコープの違いをお手すきでしたらご指導願えませんか? あとクラス変数にはセッターやゲッター等のアクセスメソッドを 設定できるんですか? いろいろ知りたいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • siffon9
  • ベストアンサー率64% (136/211)
回答No.1

クラス変数は同一クラスのインスタンス間で同じ変数を用意します。 なので、インスタンスfooでセットした値がインスタンスbarで読めます。 インスタンス変数は、各インスタンスで別々の変数を用意します。 なのでインスタンスfooでセットした値は、インスタンスbarでは読めません。 インスタンスbarで読めるのは、インスタンスbarでセットした値です。 クラス変数は、当然アクセスメソッドも書けます(インスタンス変数みたいに楽が書き方はできませんが) class Foo attr_accessor :b def initialize @@a = 0 #クラス変数初期化 @b = 0 #インスタンス変数初期化 end def set_a(x) # クラス変数@@aに設定 @@a = x end def get_a # クラス変数@@aの値読み出し @@a end def print_var puts "@@a = #{@@a}" puts "@b = #{@b}" end end foo = Foo.new bar = Foo.new puts "インスタンスfooの変数を表示" foo.print_var puts "インスタンスbarの変数を表示" bar.print_var puts "インスタンスfooのクラス変数@@aに10をセット" foo.set_a(10) puts "インスタンスfooのインスタンス変数@@aに20をセット" foo.b = 20 puts "インスタンスfooの変数を表示" foo.print_var puts "インスタンスbarの変数を表示" bar.print_var puts "インスタンスbarのクラス変数@@aに100をセット" bar.set_a(100) puts "インスタンスbarのインスタンス変数@@aに200をセット" bar.b = 200 puts "インスタンスfooの変数を表示" foo.print_var puts "インスタンスbarの変数を表示" bar.print_var 実行結果 インスタンスfooの変数を表示 @@a = 0 @b = 0 インスタンスbarの変数を表示 @@a = 0 @b = 0 インスタンスfooのクラス変数@@aに10をセット インスタンスfooのインスタンス変数@@aに20をセット インスタンスfooの変数を表示 @@a = 10 @b = 20 インスタンスbarの変数を表示 @@a = 10   ←インスタンスfooに書いた値が読める @b = 0    ←インスタンスfooに書いた値は読めない インスタンスbarのクラス変数@@aに100をセット インスタンスbarのインスタンス変数@@aに200をセット インスタンスfooの変数を表示 @@a = 100   ←インスタンスbarに書いた値が読める @b = 20    ←インスタンスbarに書いた値は読めない インスタンスbarの変数を表示 @@a = 100 @b = 200

noname#208914
質問者

お礼

とてもわかりやすい例をあげて説明してくれて有難うございます。 すごい理解がふかまりました。 同一IDのインスタント内でのみ共有可能なんですね。 クラスはそのクラス自体で共有可能だってこともこれでわかりました。 ありがとうございました!!

noname#208914
質問者

補足

インスタンス変数の@@aは@bに直して書きました

その他の回答 (1)

  • notnot
  • ベストアンサー率47% (4900/10358)
回答No.2

>スコープの違い スコープというのはソース上のレキシカルなスコープということでいいですか? どちらも自明ですが、クラス変数は、class文から対応するend文までの間すべて。 インスタンス変数はインスタンスメソッドを定義するdef文と対応するend文の間。 もし、変数の生存期間のことであれば、クラス変数は最初に代入されてからプログラム終了までずっと。インスタンス変数はオブジェクトの生成後、最初に代入または参照されてからそのオブジェクトが参照されなくなるまで。 >あとクラス変数にはセッターやゲッター等のアクセスメソッドを設定できるんですか? 自分でdef ~ endで定義すれば出来ます。attr_accessor のような仕組みは無いです。

noname#208914
質問者

お礼

ありがとうございました。 大変参考になりました!!