Rubyスクリプトの#!行でバージョンをつけるべきたったひとつの理由

俺は使っているRubyの処理系はほぼすべて保持している。というのは、Rubyのバージョンが上がるととたんに動かなくなるスクリプトが出てくるからである。
実際、 /usr/local/bin 以下にあるRuby処理系は30個くらいある。1.4.5や1.6.6といった化石バージョンすら入っている。

$ (cd /usr/local/bin; ls ruby1*)
ruby145  ruby18-trunk  ruby186p110  ruby187      ruby187p71  ruby191p0
ruby16   ruby180       ruby186p114  ruby187p160  ruby187p72  ruby191p129
ruby165  ruby181       ruby186p286  ruby187p17   ruby19      ruby191p243
ruby166  ruby186       ruby186p368  ruby187p173  ruby190     ruby191p376
ruby18   ruby186-p110  ruby186p369  ruby187p248  ruby191

Ruby 1.8系は本来ならアップデートしてもそのまま動くよう互換性があるはずだった。しかし、Route 477(2009-02-12)にあるようにRuby 1.8.7だとRuby 1.8.6以前の一部のスクリプトが動かなかったのは記憶に新しい。そういう事故は起こり得るので、自衛できるなら自衛しておいたほうがいい。

複数のバージョンのRubyを入れるには、「./configure --program-suffix=187」のように --program-suffix をつけてコンパイル・インストールすればよい。もっと徹底するには「./configure --prefix=/pkgs/ruby-1.8.7 --program-suffix=187」のように --prefixをつけておく。

そして実行スクリプトの#!行には「#!/usr/bin/env ruby187」のようにバージョンも付記しておく。主流となるバージョンが上がったとしても、このスクリプトは動き続けることができる。rubyにしておくとバージョンが上がると動かない可能性がでてきてしまう。大昔Ruby 1.6.6で書いたスクリプトは今でも正しく動作している。

公開・保守するスクリプトは新バージョンに対応する必要はある。けれども、個人用のスクリプトは古いバージョンでもまったくかまわないのだ。