- ベストアンサー
インスタンス変数とクラス変数の違い
1つのクラスオブジェクト内のインスタンス全てで共有できる クラス変数 @@a と、 同じインスタンス内であればメソッドの定義を越えてその値を 参照したり、変更したりできるインスタンス変数 @a のスコープの違いをお手すきでしたらご指導願えませんか? あとクラス変数にはセッターやゲッター等のアクセスメソッドを 設定できるんですか? いろいろ知りたいです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
クラス変数は同一クラスのインスタンス間で同じ変数を用意します。 なので、インスタンス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
その他の回答 (1)
- notnot
- ベストアンサー率47% (4900/10358)
>スコープの違い スコープというのはソース上のレキシカルなスコープということでいいですか? どちらも自明ですが、クラス変数は、class文から対応するend文までの間すべて。 インスタンス変数はインスタンスメソッドを定義するdef文と対応するend文の間。 もし、変数の生存期間のことであれば、クラス変数は最初に代入されてからプログラム終了までずっと。インスタンス変数はオブジェクトの生成後、最初に代入または参照されてからそのオブジェクトが参照されなくなるまで。 >あとクラス変数にはセッターやゲッター等のアクセスメソッドを設定できるんですか? 自分でdef ~ endで定義すれば出来ます。attr_accessor のような仕組みは無いです。
お礼
ありがとうございました。 大変参考になりました!!
お礼
とてもわかりやすい例をあげて説明してくれて有難うございます。 すごい理解がふかまりました。 同一IDのインスタント内でのみ共有可能なんですね。 クラスはそのクラス自体で共有可能だってこともこれでわかりました。 ありがとうございました!!
補足
インスタンス変数の@@aは@bに直して書きました