File.realpath

File.realpath (と File.realdirpath) を提供するのはどうでしょうか。

require_relative を呼び出したファイルをシンボリックリンクを通して
指定したとき、実体のファイルからの相対パスでないライブラリを
ロードしてしまうことがあります。

% ls -l a b
a:
total 8
-rw-r–r-- 1 akr akr 13 Jan 12 01:08 lib.rb
-rw-r–r-- 1 akr akr 23 Jan 12 01:08 tst.rb

b:
total 4
-rw-r–r-- 1 akr akr 13 Jan 12 01:08 lib.rb
lrwxrwxrwx 1 akr akr 11 Jan 12 01:08 tst.rb -> …/a/tst.rb
% cat a/tst.rb
require_relative “lib”
% cat a/lib.rb
p “a/lib.rb”
% cat b/lib.rb
p “b/lib.rb”
% ./ruby a/tst.rb
“a/lib.rb”
% ./ruby b/tst.rb
“b/lib.rb”

つまり、a/tst.rb は a/lib.rb をロードすることを期待して
require_relative を使っているのに
b/tst.rb というシンボリックリンク経由で実行した時は、b/lib.rb を
ロードしてしまいます。

これを防ぐには require_relative 内で呼び出したファイルのパス名の
シンボリックリンクを解決すればいいのですが、
これを行うメソッドは組み込みにはありません。

そこで、pathname.rb の Pathname#realpath を C で書き直して
File.realpath を実装してみました。
(他の File のパス名を操作するクラスメソッド同様、
文字列を受け取って文字列を返します。)

(なお C の realpath はバッファの大きさを指定できない危険な関数なので禁止です)

また、Pathname#realpath と実装が共有されている Pathname#realdirpath も
File.realdirpath として提供してあります。

で、require_relative で File.realpath を使って、b/tst.rb ã‚’å®Ÿè¡Œã—ãŸå ´åˆã§ã‚‚
a/lib.rb をロードするように
してみました。

% ./ruby a/tst.rb
“a/lib.rb”
% ./ruby b/tst.rb
“a/lib.rb”

どうでしょう?

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:40040] File.realpath”
on Tue, 12 Jan 2010 01:54:59 +0900, Tanaka A. [email protected]
writes:

|File.realpath (e$B$He(B File.realdirpath) e$B$rDs6!$9$k$N$O$I$&$G$7$g$&$+!#e(B

|e$B$I$&$G$7$g$&e(B?

e$B$$$$$s$8$c$J$$$G$7$g$&$+!#e(B