技術開発日記

技術やら日々思ったことを綴ってます。

インスタンス変数・クラス変数・クラスインスタンス変数

インスタンス変数、クラス変数、クラスインスタンス変数。
この3つの変数に関してスコープとか参照方法がいまいちわからなかったので、ちょっと調べてみた。

class Sample
  #クラス変数
  @@var1 = 1
  
  #クラスインスタンス変数
  @var2 = 2
  
  def initialize
  #インスタンス変数
    @var3 = 3
  end
  
  #クラスメソッドを定義
  def self.method1
    @@var1, @var2, @var3
  end
  
  #インスタンスメソッドを定義
  def method2
    @@var1, @var2, @var3
  end
end

p Sample.method1 #=> [1, 2, nil]
p Sample.new.method2 #=> [1, nil, 3]

上記の通り、クラス変数の@@var1は特にスコープを意識せず、どこからでも参照できることがわかるのでこれは特に問題ない。
もちろん継承したクラスからもアクセスできる。
いわゆるjavaでいうstatic変数みたいなものだと思う。

ただ、@var2と@var3に関してはどこに格納されているかを意識する必要があるみたい。
たとえば、@var2はクラスの中で設定されてるから、これはそのままSampleクラスに格納されるってことになる。
なんで、変数へのアクセスはインスタンスメソッドからじゃなくて、クラスメソッドからしかできないっていうことになるみたい。
これもおそらくjavaでいうstaticメソッドからstaticじゃない変数にアクセスができないといった感じになるんだと思う。

同じような感じで@var3もメソッドの中で設定されていることから、Sampleクラスのオブジェクトに格納されるインスタンスメソッドとなり、インスタンスメソッドからのみのアクセスをできるようになる。
おそらくここで、attr_reader、attr_writer、attr_accessorとかの出番になるのだろう。


という感じで、よくよく考えてみるとそんなに難しいことはないんだけど、javaと全然扱い方が違うせいか理解するまでは結構時間がかかった。

他にも継承関係による変数の参照方法とか特異メソッドからの参照方法とかもあるから、これはこれでまた時間があったら詳しく調べたい。

※理由はよく読んでなかったけど、多くの Rubyist はクラス変数を使わずにクラスインスタンス変数を使っているってどこかのブログに書いてあった。。