変数や定数のスコープ範囲をまとめてみました。
変数のスコープ範囲
# 有効パターン1
x = 5
puts x # => 5
# 有効パターン2
def number
n = 10
puts n
end
# メソッドの呼び出し
number # => 10
# エラーパターン3
x = 5
def number
puts x
end
# メソッドの呼び出し
numser # => エラー
# エラーパターン4
def number
n = 10
end
# numberメソッド内の変数nの呼び出し
puts n # => エラー
メソッドやブロック内で定義された変数は、メソッドやブロック内でしか使えなく、外部からのアクセスはできない。
定数のスコープ範囲
# 定数
MY_NUMBER = 100
def number
puts MY_NUMBER
end
# メソッドの呼び出し
number # => 100
puts MY_NUMBER # => 100
定数はメソッドの外からもアクセスすることができる。Rubyでは、定数は大文字で始まる名前で定義され、通常はクラスやモジュールの中で使われるが、トップレベルで定義した場合も、メソッドの内外からアクセス可能。
番外編
Rubyには変数、定数以外にもインスタンス変数やクラス変数、グローバル変数といったものがある
インスタンス変数
class MYCLASS
def initialize
@my_number = 100 # インスタンス変数
end
def number
puts @my_number
end
end
# インスタンスを生成
obj = MYCLASS.new
# MYCLASS内のnumberメソッドを呼び出す
obj.number # => 100
クラス内で定義されインスタンス間で共有されない変数。メソッド内外で使うことができる。
ちなみにMYCLASS内にあるinitializeメソッドは特殊なメソッドでインスタンスを生成した際に自動的に呼び出されるコンストラクタであり生成したインスタンスの初期化処理を行うメソッド。
クラス変数
class MYCLASS
@@my_number = 1000 # クラス変数
def number
puts @@my_number
end
end
# インスタンスを生成
obj = MYCLASS.new
# numberメソッド内のクラス変数@@my_numberを呼び出す
obj.number # => 1000
クラス変数はクラス内で定義され、クラス全体で共有できる変数。
グローバル変数
$global_number = 50 # グローバル変数
def number
puts $global_number
end
# メソッドの呼び出し
number # => 50
puts $global_number # => 50
グローバル変数はどこからでもアクセス可能だが、グローバルな状態を管理するのはリスクが高く、あまり推奨されていない。またグローバル変数は別のファイルからでもアクセスできる変数であり、上書きも可能。
まとめ
メソッドの外から呼び出す際、必ずしも定数で定義しなければならないわけではないが、ローカル変数の場合はスコープの制約があり、外からはアクセスできない。もしメソッドの外から変数にアクセスしたい場合、定数やインスタンス変数、クラス変数、グローバル変数などを使う必要がある。