Railsでアプリを開発中、外部APIを叩く処理でURIライブラリを使用する場面がありました。
URIライブラリは組み込みライブラリではないので、コード内にrequire 'uri'
が必ず必要だと思っていたのですが、require無しでも動いたため、その理由について調べたことをまとめます。
Rubyライブラリの種類
本題に入る前にRubyライブラリの種類について簡単に。
①組み込み標準ライブラリ
- Ruby本体に組み込まれている。
- require を書かなくても使うことができる。
- 例)Array, Hash, String, Integer
②組み込みではない標準ライブラリ(この記事で扱います)
- Ruby本体に付属している。
- インストール不要でコード内でrequireして使う。
- 例)Date, Uri, Net/http, Base64
③gem
- 有志の開発した外部ライブラリ。
- インストールが必要。
- 例)devise, rspec, rails-i18n
冒頭で挙げたURIライブラリは、②組み込みではない標準ライブラリなので、requireが必要そうですが、、
結論:Railsが自動で読み込んでくれます
Railsには、クラスやモジュールを初めて参照した際、自動的に読み込んでくれる機能が備わっています。
たとえば、以下のように、require 'uri'
無しで初めてURIクラスが登場したとします。
module GoogleApiConnectable
extend ActiveSupport::Concern
def get_place_details(place_id)
uri = URI.parse("https://maps.googleapis.com/maps/api/place/details/json")
このとき、自動でuri.rbの検索が走り、$LOAD_PATH
というRubyの組み込み変数が検索されます。
この$LOAD_PATH
には、「読み込み対象として検索するディレクトリのコレクション」が格納されています。
$LOAD_PATH
の中身をruby -e 'puts $LOAD_PATH'
で確認すると、私の環境では以下のような結果になります。
/opt/homebrew/Cellar/rbenv/1.2.0/rbenv.d/exec/gem-rehash
/Users/yuko/.rbenv/versions/3.1.3/lib/ruby/site_ruby/3.1.0
/Users/yuko/.rbenv/versions/3.1.3/lib/ruby/site_ruby/3.1.0/arm64-darwin22
/Users/yuko/.rbenv/versions/3.1.3/lib/ruby/site_ruby
/Users/yuko/.rbenv/versions/3.1.3/lib/ruby/vendor_ruby/3.1.0
/Users/yuko/.rbenv/versions/3.1.3/lib/ruby/vendor_ruby/3.1.0/arm64-darwin22
/Users/yuko/.rbenv/versions/3.1.3/lib/ruby/vendor_ruby
/Users/yuko/.rbenv/versions/3.1.3/lib/ruby/3.1.0
/Users/yuko/.rbenv/versions/3.1.3/lib/ruby/3.1.0/arm64-darwin22
このうち、/Users/yuko/.rbenv/versions/3.1.3/lib/ruby/3.1.0の中にuri.rbが格納されていました。
このほか、date.rb, net/http.rb, base64.rbなども見つかります。
Railsはここからファイルを見つけて実行してくれていたんですね。
*自動読み込みはRailsの機能なので、素のRubyではrequireが必須です。
おわりに
詳しい仕様については、Railsガイドの定数の自動読み込みと再読み込みにいろいろと書いてあります。(私はまだ断片的にしか理解できておりません。。)
普段何気なくフレームワークを使ってしまっていますが、こんな処理が走ってるんだ、とひとつ勉強にになりました。
参考