web-dev-qa-db-ja.com

ルビーの同じディレクトリにファイルを要求する短い方法はありますか?

(実行中のスクリプトと同じ)同じディレクトリにあるファイルを要求する短い方法はありますか?

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...はできると思いますが、それは悪です。 ;-)

56
MiniQuark

Ruby 1.9なので、require_relative

92
knut

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つの利点は、アプリケーションロジックの読み込みが自動的に実行を開始しない場合に、単体テストを実行するのが簡単になることです。

12
dvorak

上記は、他のディレクトリからスクリプトを実行している場合でも機能します。ただし、同じディレクトリ内で参照する短い形式は期待どおりに機能し、少なくとも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)

3
woods

これを標準ライブラリディレクトリ(デフォルトのロードパス$:にある場所)に配置します。

# 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'
#...
3
rampion