require_dependency

http://wiki.rails2u.com/require_dependency/
以下引用


require_dependency


require_dependency
ってなんなんだろ。しょっちゅうrailsソース内ででてくるけど。ということで調べてみた。


require_dependency
を定義している場所

activesupport/lib/active_support/dependencies.rbの

Object.send(:define_method, require_dependency)  { |file_name| Dependencies.depend_on(file_name) }

define_methodで定義してる。最初 'def

require_dependency
'
で検索したけどひっかからなくてここにたどり着くまでそこそこ時間がかかった、、、。

requireとの違い


require_dependency
で呼び出しているメソッド、depend_onは

<code> def depend_on(file_name, swallow_load_errors = false)
   unless loaded.include?(file_name)
     loaded << file_name
     begin
       require_or_load(file_name)
     rescue LoadError
       raise unless swallow_load_errors
     end
   end
 end
</code>

同じ引数で呼び出されていなければrequire_or_loadメソッドを実行する。んでrequire_or_loadメソッドは

<code> def require_or_load(file_name)
   file_name = "#{file_name}.rb" unless ! load? || file_name[-3..-1] == '.rb'
   load? ? load(file_name) : require(file_name)
 end
</code>

1行目で.rbだったり拡張子無しだったりするときの処理を。つーか解りにくいよ…。

<code>   file_name = "#{file_name}.rb" unless ( (! load?) || file_name[-3..-1] == '.rb')
</code>

load?がtrueじゃない、かつファイル拡張子が.rbじゃ無いならfilenameは"#{file_name}.rb"になる、か。ここはさして重要じゃなくて次の

<code>   load? ? load(file_name) : require(file_name)
</code>

でload?メソッドがtrueならloadメソッドで呼び出し、そうじゃなかったらrequireメソッドで呼び出しを行う。んでloadメソッドは

<code> @@mechanism = :load
 mattr_accessor :mechanism
 def load?
   mechanism == :load
 end
</code>

と定義されているため、何にも変更しなきゃrequire_dependencyを使うとloadメソッドで読み込まれると。デフォルトのgeneratorで生成した場合、RAILS_ROOT/config/environments/development.rbには

<code>Dependencies.mechanism                             = :load
</code>

RAILS_ROOT/config/environments/production.rbには

<code>Dependencies.mechanism                             = :require
</code>

と記述されてるのでproductionだとloadじゃなくてrequireされる。

で、んじゃrailsにおけるloadとrequireの大きな違いって何って事ってになるけど、fastcgiやwebrickでrails使ってる場合はloadでライブラリをロードしたときはもう一度無条件ロードされるため、ライブラリソースに変更があった場合はその変更が反映される。
requireの場合はすでに読み込んであったら読み込まない。通常のcgiで使ってる場合にはほとんど変わりなし。

だからdevelopmentではloadで、productionではrequireになってるんだね。自作ライブラリを作りったり修正したりしつつrailsの開発を進める場合はrequire_dependencyで読み込んでおくといいよ、と。