http://www.oki-osk.jp/esc/ruby/tut-03.html#3
トップレベルでのインスタンス変数は, トップレベルでのメソッド定義本体など,同じ self 値を共有する範囲で通用する…ように見えるかもしれませんが, それをあてにしてはいけません。 トップレベルで定義したメソッドは Object クラスに属するインスタンス・メソッドになります。 トップレベルの self と特別な関係は持ちません。 メソッドを別の文脈で実行したときは,その文脈の self 値を参照します。 同じトップレベル上でテストする限りは問題は出ませんから, よく分からずに使うと潜在バグの原因になります。 よほどのことがない限り,たとえ言語仕様として可能でも, 実際のプログラムでは,トップレベルでインスタンス変数を設けてはいけません。
だそうなので、ちょっと実験してみた。
@hoge = 'instance' hoge = 'local' def putsHoge puts '@ top level method' puts 'instance :' + @hoge puts 'local :' + hoge rescue puts $! end class Test def putsHoge puts '@ instance method' puts 'instance :' + @hoge rescue puts $! puts 'local :' + hoge rescue puts $! end end puts '@ top level' puts 'instance :' + @hoge puts 'local :' + hoge putsHoge は test = Test.new test.putsHoge
結果はこんな感じ。
@ top level instance :instance local :local @ top level method instance :instance undefined local variable or method `hoge' for main:Object @ instance method can't convert nil into String undefined local variable or method `hoge' for #<Test:0x1e16bf0>
トップレベルのロール変数とインスタンス変数のスコープの違いは分かったが、リンク先の記事が言っているような害の具体例はよく分からじ…
ちなみに、
未定義のローカル変数にアクセスすると NameError
未定義のインスタンス変数にアクセスすると nil
が返ってくるのな。