ocraの罠

RubyのプログラムをWindows用に配布するにはocraが便利だ。ウィルススキャンが反応したりすることもあるが、それでも便利なので使う。
今回はそのocraの話。

プログラムで使っている拡張ライブラリやrbファイルをまとめて圧縮してexeに含めてくれるのがocraだ。
使っているファイルを知るために$LOADED_FEATURESを見ている。これはrequireされたファイル名が文字列で格納された配列なので、eachするだけで全部取得することができる。
とはいえ、requireされるのはプログラム実行時なので、ocraではプログラムを実際に一度実行して、終了後に$LOADED_FEATURESを見ることで実行時に使われたファイルを知るようになっている。
ここに、落とし穴がある。

上記のようなロジックであるからして、ocraではためしに実行した時点で$LOADED_FEATURESに格納されていないファイルはexeに含めてくれない。それはつまり、例えばif文で条件分岐してrequireしているプログラムや、requireじゃなくloadで読み込んでいるファイルはexeに入らないということだ。基本的にloadは設定ファイルを読むためのものであるので、設定ファイルをexeに含むつもりでなければ問題は無い。

ocraが嫌う条件requireやloadをなんとかしてexeに含めたい場合、ocraが実行したのか普通に実行したのかを判定して、ocraからの場合のみ必要なファイルをすべてrequireしてしまう、という手が使える。
ocraから呼ばれたときはOcraクラスが定義されるので、以下のようなコードを頭のほうに突っ込んでおけば解決できる。

if defined?(Ocra)
  # ocraからの起動時
  require 'hoge'
  require 'fuga'
end