rubyの変数のスコープ


変数名の重複
変数名の重複があると、プログラムが予想外の挙動をする。昔使っていたBASICでは、すべての変数がglobalだった。つまり、サブルーチンでのみ使う変数の名前も重複してはならない。たとえば、forループなどで使うiさえも重複してはいけない。iを使ったforループの中で呼んだサブルーチンの中でiを使っていたら、問題が起きる。 一方、rubyでは特に指定しなければ、すべての変数はlocalである。サブルーチン(正確にはmethod)の中でどんな変数を使っても気にしないでよい。ブロックの中で定義した変数もそのブロックが終わったら無くなってしまう。普段は変数名にあまり気を使わないでよい。しかし、これに慣れすぎると、思わぬ失敗をする。 iteratorで使う変数は、すぐに開放されるので、同じものをよく使う。

4.times{|i| print i}
data=open("test.dat","r"){|f| f.read.split(/\n/)}
data.delete_if{|l| l=~/^#/}
data.each{|l| p l}

こんな感じだ。この数日しか使わないであろうプログラムを書き殴っていて、iteratorの中でiteratorを使ってしまった。すると、当然のことながら、この変数が重複することになる。このとき注意しなければいけないのは、iteratorの変数が前もって定義されている場合には、変更されてしまうということである。その結果、予想しない結果になってしまう。そのあたりは、次期バージョンでは仕様が変わって、おそらくエラーが出るようになるようだ。 ちなみに今日知ったのだが、イテレータは古い表現で、最近はブロック付きメソッドというらしい。