k-tokitoh

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

ふーん例外的な動きをするんだなー、と思ったのだが、「いやいや、例外ではなくこういう観点からみれば当然のこと」みたいなのがあればすごく教えてほしいです。