2009/11/20

Rubyの面白いところ Part 7 「NameErrorが起こらないとき」

値が代入されていないクラス変数が参照されると、RubyはNameErrorを起こす。それはローカル変数についても同様。しかし、クラス変数の先頭には@@というprefixがついているのに対して、ローカル変数には何もprefixがついていない。そのため、ローカル変数参照は、メソッド呼び出しのように見えるのである(何故ならRubyは括弧を省略できる)。Rubyインタプリタは、ローカル変数に対する代入を検出すると、それが変数であってメソッドではないことを知ることができるので、変数名が現れた時には値を返せる。そして、代入を検出していない場合には、Rubyはその式をメソッド呼び出しとして扱う。その名前のメソッドが存在しない場合には、RubyはNameErrorを起こす。
しかし、ここで注意することがある。Rubyインタプリタが変数に対する代入式を検出すると、その変数は存在するようになる。


a = 0.0 if false #この代入は絶対実行されない
print a # nil
print b # NameError

プログラミング言語 Ruby 第2刷 91ページ より

追記:2011/05/05
次のsnippetsはNameErrorを起こす。

for i in 1..2
  if i == 2
    print a
  else
    a = 1
  end
end
しかしながら、次のsnippetsはNameErrorを起こさない。
for i in 1..2
  if i != 2
    a = 1
  else
    print a
  end
end
参考: 2.3 ローカル変数はいつ参照可能になるのでしょうか

0 件のコメント: