Rubyのインスタンス変数について
Rubyの特徴としてよく言われるのは「すべてがオブジェクト」だが、オブジェクトであるならばインスタンス変数を持つことができる。今回はRubyのインスタンス変数についての色々。
インスタンス変数とは
Rubyでは「@」ひとつで始まる変数名が自動的にインスタンス変数になる。インスタンス変数はその時点のselfに保存されるので、ローカル変数と違ってコードのどの場所からでも同じselfでさえあれば同じ変数を参照することができる。
通常であればクラスを定義してインスタンスメソッド内で使うことになる。
class Hoge def initialize(fuga) @piyo = fuga end def piyo @piyo end end foo = Hoge.new(1) bar = Hoge.new(2) p foo.piyo #=> 1 p bar.piyo #=> 2
このコードでは@piyoが参照されるのはselfがHogeオブジェクトの時なので、Hogeオブジェクトに値が保存される。Hogeオブジェクトを複数作るとそれぞれ違う変数になって、違う値を保持することができる。
存在しないインスタンス変数を参照するとnilが返る。
class Hoge def initialize(fuga) @piyo = fuga end def piyo @piyopiyo end end foo = Hoge.new(1) p foo.piyo #=> nil
トップレベルのインスタンス変数
CRubyではトップレベルのselfはmainという名前のオブジェクトである。他の実装については知らない。
p self #=> main
selfがあるのならそこにインスタンス変数を作ることができる。
@piyo = "A" p @piyo #=> "A"
トップレベルで定義したインスタンス変数はselfがmainのときに使えるので、トップレベルのメソッドの中からでも参照できる。
def foo @piyo end @piyo = 5 p foo #=> 5
ちょっとした書き捨てスクリプトを作るときに便利かもしれない。
モジュールのインスタンス変数
モジュールもオブジェクトなのでインスタンス変数を作ることができる。モジュールがselfのときに参照することができるので、モジュール直下のコードと、モジュールメソッド内で参照できる。
module Hoge @foo = 10 def self.piyo @foo end end p Hoge.piyo #=> 10
モジュールを定義するとそのモジュールは当然コード内にひとつしかないので、これはsingletonのオブジェクトそのものである。singletonパターンなんかいらんかったんやー(暴言
クラス変数について
似たような見た目の変数でちょっと違うものにクラス変数がある。「@@」で始まる変数名がそれだ。クラス変数はselfではなくselfが所属するクラスに保持される。selfがクラスの場合は自分自身となる。
class Hoge @@piyo = 10 def fuga @@piyo end end foo = Hoge.new bar = Hoge.new p foo.fuga #=> 10 p bar.fuga #=> 10
アクセスするときにクラス変数が無い場合はスーパークラスを見にいき、一番上まで行っても無ければ無いということになる。値を読むときに無ければ例外になり、書くときに無ければ最も近いところに保存される。
このような動作のため、クラス変数をスーパークラスとサブクラスの両方で参照する場合はクラス変数を生成するタイミングに気をつけないとハマることになる。
おしまい
別に面白いネタでもなかったのでオチは無い。
以上である。