人気ブログランキング | 話題のタグを見る

代入文を関数にする理由

話が前後してしまうが、忘れないうちに書いておく。boot.rb の Rails クラスメソッドの定義を読んでいて次のようなコードを見つけた。

    def preinitializer_path
      "#{RAILS_ROOT}/config/preinitializer.rb"
    end

の部分だ、これは、

preinitializer_path = "#{RAILS_ROOT}/config/preinitializer"

のように代入文にしてもすこしも構わない。なぜあえてメソッドとして定義したのかということだ。このpreinitializer_path は別のところで、load(preinitializer_path) if File.exist?(preinitializer_path) のように使われているだけなのだ。

その第一の答えは、代入文の場合は、preinitializer_path がそれを利用する命令文より先に実行されていなければならないが、関数の場合はその制限がないということだ。preinitializer_path の定義はそれを利用するメソッドの前にあっても後にあっても構わない。これは、irb で簡単に確かめることができる。

irb(main):001:0> puts a
NameError: undefined local variable or method `a' for main:Object
        from (irb):1
        from :0
irb(main):002:0> def put; puts a; end
=> nil
irb(main):003:0> def a; 'hello'; end
=> nil
irb(main):004:0> put
hello
=> nil
irb(main):005:0>

もう一つの利点は、preinitializer_path の設定を代入文で行うと、ひょっとして別のところで preinitializer_path への代入が起きていたときに、発見しがたいバグの原因になる場合があるということだ。preinitializer_path を関数で実現しておけばそういう心配はない。その上、余計な名前空間を消費することもない。

全てを関数(メソッド)で表現するというのは、マニアックなやり方のようだが、オーバーヘッドが気にならない場合は、実用的にも意味のあることなのだ。
by tnomura9 | 2008-10-17 22:35 | Ruby | Comments(0)
<< RoR script/server RoR config/boot... >>