読者です 読者をやめる 読者になる 読者になる

実行しているrubyインタプリタを使って別のrubyスクリプトを実行する

ベンチマークをまとめて走らせるプログラムなどを書いているようなときは、
system('/usr/bin/ruby some_script.rb')

とか書きがちなのですが、
/usr/bin/rubyと固定で書いてると、
別のところにある1.9.1とかでふと実行してしようと思ったときにスクリプトを書きかえないといけないのでめんどくさいです。

require 'rbconfig'

ruby_cmd = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
system("#{ruby_cmd} some_script.rb")

と書いておけば、起動したrubyのパスで実行させることができるので、1.9.1で動くかとかも楽にチェックできますね。

# Windowsとかはうまく対応できてないかもしれません。

# ふとそういえば、rakeでもやってたような気がして、rakeのrubyメソッドの定義を見てみると大本はこんなふうになってて、

  RUBY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']).
    sub(/.*\s.*/m, '"\&"')

subとかしてるのは何でしょうねぇ。ディレクトリ名に空白が入っていた場合とかかなぁ。もしそうだとしたらgsubしないといけなさそうな気も。

追記:

id:otnさんのコメントで気づいたのですが、\&はリファレンスマニュアルとかざっと調べた感じだと載ってないような気もしますが、どうやら後方参照の一つで、おそらく組み込み変数$&と対応してるっぽい。つまりマッチさせた文字列全体なのでこのsubは空白があった場合に二重引用符で全体を囲うという意味らしいです。ひとつでもあったときに全体に適用するので、gsubでなくてsubということですね。

追記:

String#gsubの項目に説明が書いてあることを教えていただきました。正規表現の後方参照ではなくて、sub/gsubの特殊文字と呼ぶ方が正しいですね。