Rubyのrequire_relative
とrequire
の違いは何ですか?
docs を見てください。
require_relative
は、require_relative
ステートメントを含むファイルに相対的なファイルをロードできるようにすることで、組み込みメソッドrequire
を補完します。たとえば、 "test"ディレクトリに単体テストクラスがあり、test "test/data"ディレクトリの下にそれらのデータがある場合、テストケースでは次のような行を使用します。
require_relative "data/customer_data_1"
require_relative
はrequire
の便利なサブセットです
require_relative('path')
等しい:
require(File.expand_path('path', File.dirname(__FILE__)))
__FILE__
が定義されている場合、そうでない場合はLoadError
を発生させます。
これは次のことを意味します。
require_relative 'a'
およびrequire_relative './a'
requireは、現在のファイル(__FILE__
)に対して相対的です。
結果を呼び出し元の現在のディレクトリに依存させたくないので、これはライブラリ内で必要なときに使用したいものです。
eval('require_relative("a.rb")')
は、__FILE__
がLoadError
内で定義されていないため、eval
を発生させます。
これが、eval
edを取得するRSpecテストでrequire_relative
を使用できない理由です。
次の操作は、require
でのみ可能です。
require './a.rb'
は、現在のディレクトリに対して相対的である必要があります
require 'a.rb'
は、検索パス($LOAD_PATH
)を使用して要求します。現在のディレクトリまたはパスに関連するファイルは検索しません。
これはrequire_relative
では不可能です。ドキュメントでは、「ファイル名が絶対パスに解決されない」場合にのみパス検索が発生すると説明されています(つまり、/
または./
または../
)、これは常にFile.expand_path
の場合です。
両方で次の操作が可能ですが、より短く効率的なrequire
を使用する必要があります。
require '/a.rb'
とrequire_relative '/a.rb'
の両方に絶対パスが必要です。ソースの読み取り
ドキュメントが明確でない場合は、ソースを確認することをお勧めします(ドキュメントのソースを切り替えます)。場合によっては、何が起こっているかを理解するのに役立ちます。
必要なもの:
VALUE rb_f_require(VALUE obj, VALUE fname) {
return rb_require_safe(fname, rb_safe_level());
}
require_relative:
VALUE rb_f_require_relative(VALUE obj, VALUE fname) {
VALUE base = rb_current_realfilepath();
if (NIL_P(base)) {
rb_loaderror("cannot infer basepath");
}
base = rb_file_dirname(base);
return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}
これにより、
require_relative('path')
次と同じです:
require(File.expand_path('path', File.dirname(__FILE__)))
なぜなら:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
Ruby APIから:
require_relativeは組み込みメソッドrequireを補完するもので、require_relativeステートメントを含むファイルからの相対ファイルをユーザーがロードできるようにします。
ファイルをロードするためにrequireを使用するとき、あなたは通常あなたのシステムに適切にインストールされアクセス可能にされた機能にアクセスしています。 requireはプロジェクトのコード内でファイルをロードするための良い解決策を提供しません。これは開発段階で、テストデータにアクセスするために、あるいはプロジェクト内で「ロック」されているファイルにアクセスするためにも役立ちます。
たとえば、 "test"ディレクトリに単体テストクラスがあり、test "test/data"ディレクトリの下にそれらのデータがある場合、テストケースでは次のような行を使用します。
require_relative "data/customer_data_1"
"test"も "test/data"もRubyのライブラリパスにはあり得ないので(そして正当な理由で)、通常はそれらを見つける必要はありません。 require_relativeはこの特定の問題に対する良い解決策です。
ロードしているファイルの拡張子(.rbまたは.so)を含めるか省略することができます。
pathはto_strに応答する必要があります。
ドキュメントは http://extensions.rubyforge.org/rdoc/classes/Kernel.html にあります。
require
を使うrequire_relative
を使うrequire
はファイルを見つけるためにあなたの$LOAD_PATH
を使います。require_relative
は、ステートメントを使用してファイルの現在の場所を使用します
Requireはあなたがその機能のためにあなたのシステムのどこかにパッケージをインストールした(例えばgem install [package]
)ことに頼ります。
require
を使うとき、あなたはcanカレントディレクトリのファイルに "./
"フォーマットを使います。 require "./my_file"
は一般的な方法でも推奨される方法でもありません。代わりにrequire_relative
を使用してください。
これは単にファイルを 'require_relativeステートメントでファイルの場所を基準にして'含めることを意味します。 I 一般にファイルは "up"ではなく現在のディレクトリツリー内に "ある"ことをお勧めします。 しない use
require_relative '../../../filename'
ファイルシステム内で(3つのディレクトリレベルまで)これが不要で脆弱な依存関係を作成する傾向があるからです。しかし場合によっては、ディレクトリツリー内ですでに「深い」場合は、別のディレクトリツリーブランチを「上下に」使用する必要があります。もっと簡単に言えば、このリポジトリの外部のファイルにはrequire_relativeを使わないでください(あなたがgitを使っているのであれば、2018年後半には事実上の標準となっています)。
require_relative
は現在のディレクトリrequire_relativeを持つファイルのステートメントを使用していることに注意してください(だからあなたのコマンドを使っている現在のディレクトリとは限りません)。これはrequire_relative
パスを常に「安定」に保ちます。なぜなら、それは常に同じ方法でそれを必要とするファイルに相対的だからです。
正解は正しいですが、非常に技術的です。 Rubyを初めて使う人のために -
require_relative
はあなたが書いた別のファイルからコードを取り込むために使われるでしょう。たとえば、~/my-project/data.rb
にデータがあり、それを~/my-project/solution.rb
に含める場合はどうなりますか。 solution.rb
にrequire_relative 'data'
を追加します。
これらのファイルは同じディレクトリにある必要はないことに注意することが重要です。 require_relative '../../folder1/folder2/data'
も有効です。
require
は、他の人が書いたライブラリからコードを取り込むために使用される可能性があります。たとえば、active_support
ライブラリで提供されているヘルパー関数の1つを使用したい場合はどうなりますか? gemをgem install activesupport
でインストールしてからrequire 'active_support'
ファイルにインストールする必要があります。
require 'active_support/all'
"FooBar".underscore
言いました -
require_relative
は、それを呼び出すファイルに対して相対的に参照されるファイルを必要とします。
require
は、$ LOAD_PATHに含まれているファイルを必要とします。
RSpecのコードには、O(1)定数であるrequire_relative
と、O(N)であるrequire
に関するコメントがあります。おそらく、違いはrequire_relative
がrequire
よりも優先されることです。
私は、Windowsを使用しているときにスクリプトがローカルまたはマップされたネットワークドライブから実行されている場合はrequire './1.rb'
を使用できますが、UNC\servername\sharename\folderパスから実行する場合はrequire_relative './1.rb'
を使用する必要があることを付け加えます。他の理由でこれを使用します。