環境設定、パスなど

キャッシュになってたので、転載。

rubyのちょっとしたこと

rubyを使っていてちょっと疑問に思ったこと、使いやすくするためにした工夫、
どうでもいいようなことをまとめました。

●requireはどこのパスから読み込む?

巨大なプログラムを組むとなると、当然共通処理もたくさんでてきますし、
それらをライブラリとしてまとめて、とあるディレクトリに置いておきたいと思うのも人情です。

requireコマンドはそんなためにあります。
requireで示す文字列は.rbや.soを省略したファイル名なわけです。
ではrubyはこのファイルをどのパスから探すのかというと、/usr/lib/ruby/1.6/(バージョン1.6では)と、
カレントディレクトリから読むんですね。

ここでひとつ困ってしまったのは、ここでいうカレントディレクトリとは、
そのファイルがあるディレクトリではなく、
起動されたrubyスクリプトのカレントディレクトリなのです。
では、下の例を考えてください。

/home
  /taro
    main.rb(require 'lib/web.rb')
    /lib
      web.rb(require './web_sub1' : require './web_sub2')
      web_sub1.rb
      web_sub2.rb
      web_sub3.rb

/home/taro/main.rbが起動されるスクリプトです。
main.rbは/home/taro/lib/web.rbをライブラリとして読み込みます。
web.rbは自分のライブラリを完成させるために必要なweb_sub1.rbなど、
複数のファイルをrequireします。
ここでweb_sub1.rbをrequireするために、
./web_sub1と相対パスを使っていますが、これは正しくありません。
なぜなら、この例のカレントパスは、起動されたmain.rbの/home/taroだからです。
つまりこの場合、rubyは/home/taro/libではなく、/home/taroを参照にいきます。

web.rb(require 'lib/web_sub1' : require 'lib/web_sub2')

では、上のようにweb.rbでrequireするすべてにlib/web_sub1のようなパスをつけてみればどうでしょう?
/home/taro上で起動されるスクリプトについては有効ですが、
他のディレクトリからweb.rbは使えなくなってしまいます。
パスの設定をどうやっても/home/taro/libをカレントパスにできないので、対処方法を考えてみました。

絶対パスにするのは悪い手ではないのですが、よその環境にもっていくときに困ってしまいます。
rubyのlibディレクトリ(/usr/lib/ruby/1.6)に入れてしまうのは楽ではありますが、
非公式のスクリプトをわざわざroot権限使って入れるのは畏れ多いです。
グローバル変数にライブラリのパスを入れるのはちょっとダサいです。

いずれも面白そうな方法ではないので、マニュアルをあたってみることにしました。

requireで参照するパスは組み込み定数$:($LOAD_PATH)に定義されているとのことです。
ということは、この$:にライブラリのパスが追加されればいいということですね。
結局はグローバル変数に入れるのと似たようなものですが、
システムの定数なんでスマートであるといえるでしょう。
その方法は以下の通りです。

  • ruby起動時に-Iオプションで与える
% ruby -I /home/taro/lib main.rb 
% export RUBYLIB=/home/taro/lib 
  • スクリプト内で$:に追加する(main.rbの先頭に以下の行を追加)
$: << '/home/taro/lib' 

これでユーザーのライブラリパスが追加されます。