2019-06-19
Rubyにおけるローカル変数のスコープ
いまさらだけど、あれ?と思うことがあったのでメモ。
[変数と定数 (Ruby 2.6.0)](https://docs.ruby- lang.org/ja/latest/doc/spec=2fvariables.html#local)
「ローカル変数のスコープは、宣言した位置からその変数が宣言されたブロック、メソッド定義、またはクラス/モジュール定義の終りまでです。」
試してみる。
top_level = 1
class Klass
in_class = 1
def method
in_method = 1
[0].each do
in_block = 1
p defined?(top_level) # => nil
p defined?(in_class) # => nil
p defined?(in_method) # => "local-variable" # これはつかえるのか!
p defined?(in_block) # => "local-variable"
end
p defined?(top_level) # => nil
p defined?(in_class) # => nil
p defined?(in_method) # => "local-variable"
p defined?(in_block) # => nil
end
p defined?(top_level) # => nil
p defined?(in_class) # => "local-variable"
p defined?(in_method) # => nil
p defined?(in_block) # => nil
end
p defined?(top_level) # => "local-variable"
p defined?(in_class) # => nil
p defined?(in_method) # => nil
p defined?(in_block) # => nil
ローカル変数は宣言されたスコープの外側ではつかえない。上記の例でいうと…
- クラス内で宣言されたローカル変数は、そのクラスの外側ではつかえない。
- メソッド内で宣言されたローカル変数は、そのメソッドの外側ではつかえない。
- ブロック内で宣言されたローカル変数は、そのブロックの外側ではつかえない。
ローカル変数は宣言されたスコープの配下にある独立したスコープでは(基本的に)つかえない。上記の例でいうと…
- トップレベルで宣言されたローカル変数は、その配下にあるクラスの中ではつかえない。
- クラス内で宣言されたローカル変数は、その配下にあるメソッドの中ではつかえない。
- ただし!!!
- ある場所で宣言されたローカル変数は、その直下のブロック内でつかうことができる!!!
- 上記の例では、メソッド内で宣言したローカル変数が、その配下にあるブロックの中でつかえている。
トップレベル/クラス/ブロック内でローカル変数を宣言した場合も同様に、直下のブロックの中でつかうことができる。
# トップレベルの場合
top_level = 1
[0].each do
p defined?(top_level) # => "local-variable"
end
# クラスの場合
class Klass
in_class = 1
[0].each do
p defined?(in_class) # => "local-variable"
end
end
# ブロックの場合
[0].each do
in_block = 1
[0].each do
p defined?(in_block) # => "local-variable"
end
end
ふーん例外的な動きをするんだなー、と思ったのだが、「いやいや、例外ではなくこういう観点からみれば当然のこと」みたいなのがあればすごく教えてほしいです。