requireとrequire_relativeの使い分け

Sinatraのメモアプリでhelper 読込の際にrequirerequire_relative の使い分けが分からかったので調べました。

結論

gemなどのライブラリの読込にはrequire、helperなどの自前で用意したファイルの読込にはrequire_relative を使う。

相違点

参照方法が異なる。

メソッド 用途 参照方法 パスの記述例
require ライブラリ読込 1. カレントディレクトリからの絶対パス
2. rubyコマンドを実行した位置からの相対パス($LOAD_PATH)
require 'sinatra'
require_relative 自前ファイル読込 読込元のファイルからの相対パス require_relative 'helpers/crud_helper'

$LOAD_PATH とは

Rubyライブラリをロードするときの検索パスが格納されているグローバル変数相対パスで読み込むパスは以下で確認できる。

$ ruby -e 'puts $:'
/opt/homebrew/Cellar/rbenv/1.2.0/rbenv.d/exec/gem-rehash
/Users/karlley/.rbenv/versions/3.0.3/lib/ruby/site_ruby/3.0.0
/Users/karlley/.rbenv/versions/3.0.3/lib/ruby/site_ruby/3.0.0/arm64-darwin21
/Users/karlley/.rbenv/versions/3.0.3/lib/ruby/site_ruby
/Users/karlley/.rbenv/versions/3.0.3/lib/ruby/vendor_ruby/3.0.0
/Users/karlley/.rbenv/versions/3.0.3/lib/ruby/vendor_ruby/3.0.0/arm64-darwin21
/Users/karlley/.rbenv/versions/3.0.3/lib/ruby/vendor_ruby
/Users/karlley/.rbenv/versions/3.0.3/lib/ruby/3.0.0
/Users/karlley/.rbenv/versions/3.0.3/lib/ruby/3.0.0/arm64-darwin21

ここに検索対象のパスが設定されているのでrequire を使ったライブラリ読込は相対パスでイケるってことで良いのかな? ここに表示されていないライブラリの読込には絶対パスで指定する必要があるみたい。

共通点

  • 拡張子を省略できる(拡張子補完)
  • 対象ファイルの読込は1度だけ行われる
  • 対象ファイルが見つからないとLoadError を返す
  • 対象ファイルが既に読み込まれている場合はfalse を返す

まとめ

だいぶ情報が整理されてスッキリしましたが、まだ完璧ではないのでもう少し深堀りする必要がありそうです。

参照

Kernel.#require (Ruby 3.1 リファレンスマニュアル)

Kernel.#require_relative (Ruby 3.1 リファレンスマニュアル)

$-I (Ruby 3.1 リファレンスマニュアル)

requireとrequire_relativeとloadの違いをまとめておく

Ruby require と require_relative の違い - No Solution for Life