読者です 読者をやめる 読者になる 読者になる

【Ruby】変数と定数ついて

Ruby
スポンサーリンク

Rubyの変数と定数についてです。変数については慣れてくると意識しなくても使い分け出来るようになるんですが、最初は思わぬところで落とし穴にはまってたりして悩む事がよくありますよね。

ローカル変数

先頭がアルファベットの小文字か_で始まり、数字で始めると例外が発生します。また、最初に値が代入されたときに初期化されるため、初期化されていないローカル変数を参照した場合は、引数のないメソッドの呼び出しとみなされて例外が発生します。

name = "Ruby"  # OK
_name = "Ruby"  # OK
1name = "Ruby" # エラー
name  # 事前に代入してない場合エラー

ローカル変数は同じスコープ内でのみ使用できる変数で、別のスコープで同じ名前の変数を使ったとしても別のローカル変数として扱われるため、次のように別メソッドで同じ名前の変数に値を代入した場合でも影響されません。

class Local
    def hoge
        name = "Ruby"  # hogeメソッド内のローカル変数
        fuga  # fugaメソッド実行
        p name  # nameを表示
    end
    def fuga
        name = "Java"  # fugaメソッド内のローカル変数
    end
end

local = Local.new
local.hoge
#=>"Ruby"

グローバル変数

先頭が「$」で始まります。「$」のあとに数字を付けることは出来ません。また、ローカル変数と違い初期化されていないグローバル変数を参照した場合でも例外は発生しませんが、nilが返ります。

$name1  # OK
$1name  # エラー

グローバル変数はプログラム中のどこで使われても同じ名前であれば、同じ変数として扱われます。一見便利そうですがあまり使う機会はなさそうです。どこからも参照できて変更もできるとなると色々と問題もありますから。Javaでいうとfinalのないstatic変数ですね。

インスタンス変数

「@」で始まる変数をインスタンス変数といいます。「@」のあとに数字を付けることはできません。初期化してないインスタンス変数を参照するとnilが返ります。

ローカル変数はメソッドごとに異なる変数として扱われますが、インスタンス変数は、同じインスタンス内であればメソッド定義を超えて、その値を参照したり変更したりできます。また、クラスの外部から直接アクセスすることはできません。

class Programing
    @name
    def name=(value)
        @name = value
    end 
    def output
        p @name
    end 
end

hoge = Programing.new  # インスタンス1生成
fuga = Programing.new  # インスタンス2生成

hoge.name = "Ruby"  # インスタンス1の変数にセット
fuga.name = "Java"  # インスタンス2の変数にセット

hoge.output
#=>"Ruby"
fuga.output
#=>"Java"

クラス変数

「@@」で始まる変数をクラス変数といいます。「@@」のあとに数字を付けることはできません。初期化してないインスタンス変数を参照するとnilが返ります。

クラス変数はそのクラスのすべてのインスタンスで共有できる変数です。グローバル変数と似てますが、同じクラス内でのみになります。クラスの外部から直接アクセスすることはできません。これも使いどころが難しいですね。

class Programing
    @@name
    def name=(value)
        @@name = value
    end 
    def output
        p @@name
    end 
end

hoge = Programing.new  # インスタンス1生成
fuga = Programing.new  # インスタンス2生成

hoge.name = "Ruby"  # インスタンス1の変数にセット
fuga.name = "Java"  # インスタンス2の変数にセット

hoge.output
#=>"Java"
fuga.output
#=>"Java"

擬似変数

これはRubyに予約された変数ですので、値を代入しようとするとエラーになります。よく出てくる nil や false , true などが擬似変数にあたります。

定数

定数はアルファベットの大文字で始まります。ただし、慣習として識別子はすべて大文字で、単語の区切りを「_」とします。

クラスで定義できますが、メソッドの中では定義できません。値が代入されることによって初期化・定義されるため、定義されていない定数にアクセスすると例外が発生します。また、定義されている定数に値を代入しようとすると警告があります。

class Foo
    Homepage = "google"
    ...
    def bar
        Site = "yahoo"  # エラー
    end
end

定数にアクセスするには内部からはそのまま定数名でアクセスできますが、外部のクラスからの場合は、次のように参照します。

p Foo::Homepage