web-dev-qa-db-ja.com

Rubyにおけるrequire_relativeとrequireの違いは何ですか?

Rubyのrequire_relativerequireの違いは何ですか?

288
agentbanks217

docs を見てください。

require_relativeは、require_relativeステートメントを含むファイルに相対的なファイルをロードできるようにすることで、組み込みメソッドrequireを補完します。

たとえば、 "test"ディレクトリに単体テストクラスがあり、test "test/data"ディレクトリの下にそれらのデータがある場合、テストケースでは次のような行を使用します。

require_relative "data/customer_data_1"
286
miku

require_relativerequireの便利なサブセットです

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を発生させます。

    これが、evaledを取得する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 にあります。

74
svilenv

概要

インストールされているgemにrequireを使う

ローカルファイルにrequire_relativeを使う

requireはファイルを見つけるためにあなたの$LOAD_PATHを使います。
require_relativeは、ステートメントを使用してファイルの現在の場所を使用します


要求する

Requireはあなたがその機能のためにあなたのシステムのどこかにパッケージをインストールした(例えばgem install [package])ことに頼ります。

requireを使うとき、あなたはcanカレントディレクトリのファイルに "./"フォーマットを使います。 require "./my_file"は一般的な方法でも推奨される方法でもありません。代わりにrequire_relativeを使用してください。

require_relative

これは単にファイルを 'require_relativeステートメントでファイルの場所を基準にして'含めることを意味します。 I 一般にファイルは "up"ではなく現在のディレクトリツリー内に "ある"ことをお勧めします。 しない use

require_relative '../../../filename'

ファイルシステム内で(3つのディレクトリレベルまで)これが不要で脆弱な依存関係を作成する傾向があるからです。しかし場合によっては、ディレクトリツリー内ですでに「深い」場合は、別のディレクトリツリーブランチを「上下に」使用する必要があります。もっと簡単に言えば、このリポジトリの外部のファイルにはrequire_relativeを使わないでください(あなたがgitを使っているのであれば、2018年後半には事実上の標準となっています)。

require_relativeは現在のディレクトリrequire_relativeを持つファイルのステートメントを使用していることに注意してください(だからあなたのコマンドを使っている現在のディレクトリとは限りません)。これはrequire_relativeパスを常に「安定」に保ちます。なぜなら、それは常に同じ方法でそれを必要とするファイルに相対的だからです。

42
Michael Durrant

正解は正しいですが、非常に技術的です。 Rubyを初めて使う人のために -

  • require_relativeはあなたが書いた別のファイルからコードを取り込むために使われるでしょう。

たとえば、~/my-project/data.rbにデータがあり、それを~/my-project/solution.rbに含める場合はどうなりますか。 solution.rbrequire_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に含まれているファイルを必要とします。

23

RSpecのコードには、O(1)定数であるrequire_relativeと、O(N)であるrequireに関するコメントがあります。おそらく、違いはrequire_relativerequireよりも優先されることです。

14
mech

私は、Windowsを使用しているときにスクリプトがローカルまたはマップされたネットワークドライブから実行されている場合はrequire './1.rb'を使用できますが、UNC\servername\sharename\folderパスから実行する場合はrequire_relative './1.rb'を使用する必要があることを付け加えます。他の理由でこれを使用します。

1
peter