Rubyにおけるローカル変数のスコープ規則

Rubyにおけるローカル変数のスコープ規則を再確認しました。
仕様については、書籍「Ruby技術社認定試験 公式ガイド」を参考にしています。

要注意と思われるのは以下の点です。

  • メソッド定義の外側で宣言された (=初めて代入された) ローカル変数のスコープは、メソッド定義の内側には及ばない。
  • ブロックの内側で宣言されたローカル変数のスコープは、ブロックの外側には及ばない。
  • ブロックの外側で宣言されたローカル変数は、ブロックの内側でも有効である。

2点目、3点目は経験的に分かりますが、1点目は特に引っかかりやすいポイントかと思います。

RUBY技術者認定試験 公式ガイド (ITpro BOOKs)

RUBY技術者認定試験 公式ガイド (ITpro BOOKs)

一応、簡単なサンプルプログラムを書いて挙動を確かめてみました。

メソッド定義の外側で宣言されたローカル変数

サンプルプログラム: test1.rb

class SomeClass
  v = 20
  def hello
    puts "Hello, world: #{v}"
  end
end

s = SomeClass.new
s.hello

実行結果:

$ ruby test1.rb 
test1.rb:4:in `hello': undefined local variable or method `v' for #<SomeClass:0x9b775ac> (NameError)
	from test1.rb:9:in `<main>'

ブロックの内側で宣言されたローカル変数

サンプルプログラム test2.rb:

class SomeClass
  def hello
    2.times {
      v = 10
    }
    puts "Hello, world: #{v}"
  end
end

s = SomeClass.new
s.hello

実行結果:

$ ruby test2.rb 
test2.rb:6:in `hello': undefined local variable or method `v' for #<SomeClass:0x91eb3f4> (NameError)
	from test2.rb:11:in `<main>'

ブロックの外側で宣言されたローカル変数

サンプルプログラム test3.rb:

class SomeClass
  def hello
    v = 0
    2.times {
      v = 10
    }
    puts "Hello, world: #{v}"
  end
end

s = SomeClass.new
s.hello

実行結果:

$ ruby test3.rb 
Hello, world: 10