こんにちは。
今年は花粉影響が大きく、外出するのが辛い小林です。
今回はRuby on Rails
(以下、Rails)を使用するようになってから、ずっと気になっていたことが(たくさん)あるのですが、それが1つ解決しました!!
その喜びを伝えたく、キーボードを執りました。
今回のテーマは、これです。
なぜ、bundler
でインストールしたgem
をrequire
せずに使用することができるのか?
はじめに
Rubyの勉強を始めたときにこういうことを覚えますよね?
外部ファイルを使用する場合は
require
にて対象のファイルをロードする
しかし、bundler
とRails
を組み合わせて使用している際に、require
を使用しませんよね?
なぜなのでしょうか?
なぜ、reuqireを省略することができるのか?
皆さんは、なぜだと思いますか?

実は、require
しなくても呼び出すことができる?

いいえ。
それだとrequire
の存在意義がなくなってしまいます笑

「require
は同じファイルを複数回ロードしない」ということは、一度ロードされてしまえば、再度require
を実行する必要ない。
つまり、すでにどこかでrequire
が実行されている?

よいところに目をつけましたね。
それでは、答え合わせをしていきましょう。
答え合わせ
答えは以下のファイルにあります。
config/application.rb
config/apprlication.rb
このファイル内で以下の記述があります。
Bundler.require(*Rails.groups)
参考:yasslab/sample_apps/blob/main/6_0/ch14/config/application.rb#L7
この処理によってGemfile
に記載されているgem
が依存関係を含めてロードすることができるようになります。
If you have a lot of dependencies, you might want to say “require all of the gems in myGemfile
“. To do this, put the following code immediately followingrequire 'bundler/setup'
:Bundler.require(:default)
参考:How to use Bundler with Ruby#Setting Up Your Application to Use Bundler
ソースコード的な解説をしだすと切りがないので省略しますが、興味がある方は以下を参考にしてください。
参考:bundler/lib/bunder.rb
Bundler.require
でGemfile内のgemをロードするのはわかったのですが、そもそもBundler
自体もgem
なので、どこかでrequire
しないといけないのでは?
上記に記載がある通り、require 'bundler/setup'
の後に実施するように記載されています。
該当コードを確認すると内部でBundler
をロードしています。
参考:bundler/lib/bundler/setup.rb
最後の疑問です。
config/application.rb
内では、require 'bundler/setup'
を実施していないではないですか。
config/boot.rb
config/application.rb
内でrequire_relative 'boot'
を実施しています。
config/boot.rb
を確認すると、require 'bundler/setup'
を実施していることが確認できます。
参考:yasslab / sample_apps sample_apps/6_0_0/ch14/config/boot.rb
注意事項
以下のように:require => false
と指定すると、Bundler.require
を実行しても、ロードされないので、注意してください。
Specify :require => false to prevent bundler from requiring the gem, but still install it and maintain dependencies.
gem 'rspec', :require => false gem 'sqlite3'参考:Gemfiles
最後に
最初のRails案件でプルリクエスト出した際に、「個別のrequire
は不要」と指摘されて依頼、ずっと気にかけていたことなので、本当によかったです。
完全に理解しました。(Railsガイドちゃんと読まないと。。。)
他にも気になっているものは多々あるので、引き続き調査していこうと思います。