ぎょーぼのぶろぐ

IT系の話を書いていくブログです。今はRubyの勉強中。

【Ruby】require と require_relative

前置き

requirerequire_relative の違いと注意点についてです。

require

require は、引数で与えられたファイルパスのファイルを一度だけ呼び出します。このとき、引数のパスは、絶対パスでも相対パスでもOKで、相対パスの場合は、requireが呼ばれた時点でのカレントディレクトリからの相対パスになります。

C:\gyobo\test\ ディレクトリに、a.rbreq.rb の2つのファイルを置き、a.rb ファイルには、

require "req.rb"

とし、req.rb は、

p "required `req.rb`!"

と書いておきます。これで、カレントディレクトリを変えたりして a.rb を実行してみると、、、

C:\gyobo\test>ruby a.rb       # => "required `req.rb`!"

C:\gyobo>test\ruby a.rb       # => ruby: No such file or directory -- a.rb (LoadError)

カレントディレクトリが合っていないと、ファイルが見つからずに LoadError となってしまいます。

require_relative

require_relative も、引数で与えられたファイルパスのファイルを一度だけ呼び出しますが、相対パスが与えられた場合、実行しているファイルのある場所からの相対パスとして解釈してくれます。

先ほどと同じように、C:\gyobo\test\ ディレクトリに、a.rbreq.rb の2つのファイルを置いた状態で、a.rb ファイルの方を、

require_relative "req.rb"

に書きかえて、同じように実行してみると、、、

C:\gyobo\test>ruby a.rb       # => "required `req.rb`!"

C:\gyobo>test\ruby a.rb       # => "required `req.rb`!"

となり、実行するカレントディレクトリの場所に関係が無くなり、実行しているファイルの相対パスで呼び出せるようになります。

require_relative の注意点

require_relative では、__dir__と同様にシンボリックリンクを解決します。

例えば、C:\gyobo\test2\ ディレクトリに、sl_a という名前で C:\gyobo\test\a.rb へのシンボリックリンクを作成します。その状態で、sl_a を実行すると、、、

C:\gyobo\test2>ruby sl_a       # => "required `req.rb`!"

test2 ディレクトリにある sl_a ファイルを実行していますが、ちゃんと test\req.rb が呼び出されています。また、req.rbtest2 ディレクトリに移動させて実行すると、、、

C:\gyobo\test2>ruby sl_a
Traceback (most recent call last):
        1: from sl_a:1:in `<main>'
sl_a:1:in `require_relative': cannot load such file -- C:/gyobo/test/req.rb (LoadError)

実行しているのは sl_a ですが、C:/gyobo/test/req.rb を探しに行っているのが分かります。require_relativeは、あくまで実体ファイルのある場所からの相対パスで探索する、ということを忘れないように注意しましょう。