ルビーの同じディレクトリにファイルを要求する短い方法はありますか?
(実行中のスクリプトと同じ)同じディレクトリにあるファイルを要求する短い方法はありますか?
require File.expand_path(File.dirname(__FILE__) + '/some_other_script')
私はrequire "my_script"
とrequire "./my_script"
が実際にスクリプトを2回ロードすることを読みました(Rubyはそれが実際に同じスクリプトであることを認識しません)。これがFile.expand_path
が推奨される理由です。スクリプトが必要になるたびに使用され、その後、一度だけロードされます。
Rubyのような簡潔な言語は、より短い解決策を持っているようには見えません。例えば、pythonは単にこれを持っています:
import .some_other_module_in_the_same_directory
モンキーパッチrequire
...はできると思いますが、それは悪です。 ;-)
Ruby 1.9なので、require_relative
。
filename
が必要です。
はい、filename
と./filename
を指定すると、2回インポートされます。そのため、インポートしないでください。 .rb
を指定していないため、パスを指定しないでください。私は通常、アプリケーションロジックの大部分をlib
のファイルに入れ、次にbin
に次のようなスクリプトを作成します。
#!/usr/bin/env Ruby
$: << File.join(File.dirname(__FILE__), "/../lib")
require 'app.rb'
App.new.run(ARGV)
もう1つの利点は、アプリケーションロジックの読み込みが自動的に実行を開始しない場合に、単体テストを実行するのが簡単になることです。
上記は、他のディレクトリからスクリプトを実行している場合でも機能します。ただし、同じディレクトリ内で参照する短い形式は期待どおりに機能し、少なくともRuby 1.9の場合は、二重の要求は行われません。
testa.rb
puts "start test A"
require 'testb'
require './testb'
puts "finish test A"
testb.rb
puts "start test B"
puts "finish test B"
「Ruby testa.rb」を実行すると、次のようになります。
start test A
start test B
finish test B
finish test A
ただし、長い形式は別のディレクトリからでも機能します(例Ruby somedir/script.rb)
これを標準ライブラリディレクトリ(デフォルトのロードパス$:
にある場所)に配置します。
# Push-loadpath.rb
if caller.first
$: << File.expand_path(File.dirname(caller.first))
end
次に、これはうまくいくはずです
% ls /path/to/
bin.rb lib1.rb lib2.rb #...
% cat /path/to/bin.rb
load 'Push-loadpath.rb'
require 'lib1'
require 'lib2'
#...
caller
は、現在のコールスタックへのアクセスを提供し、どのファイルと場所を通知します。そのため、Push-loadpath.rb
は、それを使用して、load
でロードしたファイルをロードパスに追加します。
load
ではなく、ファイルをrequire
する必要があることに注意してください。これにより、本文を複数回呼び出すことができます(ロードパスを変更するたびに1回)。
または、メソッドで本体をラップすることもできます。
# Push-loadpath.rb
def Push_loadpath
$: << File.expand_path(File.dirname(caller.first))
end
これはそれをrequire
することを可能にし、次のように使用します:
% ls /path/to/
bin.rb lib1.rb lib2.rb #...
% cat /path/to/bin.rb
require 'Push-loadpath'
Push_loadpath
require 'lib1'
require 'lib2'
#...