Gemfile に書く require: false とは何か

久しぶりに Rails アプリを1から作るにあたり、Rubocop を導入しようとしたらいろいろと疑問が出てきたので調べた。

Rails アプリに Rubocop を入れる文脈で、こんな書き方をよく見かける。

Gemfile

gem 'rubocop', require: false
gem 'rubocop-rails', require: false

今さらだけど、require: falseって何だったっけ??

require をしないようにする設定っぽいが、そういえば、Rails アプリの場合各ファイルで require しなくていいのはなぜ?

手元にあった RubyRails の本を4冊見てみたところ、Bundler の基本的な使い方などはどの本にも書いてあったが、Bundler を使うとrequireがいらなくなるなんていう記述はない。

Bundler のドキュメントを読んでみる。

Gemfile の require についての項目。

Each gem MAY specify files that should be used when autorequiring via Bundler.require. You may pass an array with multiple files or true if the file you want required has the same name as gem or false to prevent any file from being autorequired.

gem "redis", :require => ["redis/connection/hiredis", "redis"]
gem "webmock", :require => false
gem "byebug", :require => true

The argument defaults to the name of the gem. For example, these are identical:

gem "nokogiri"
gem "nokogiri", :require => "nokogiri"
gem "nokogiri", :require => true

Bundler: gemfile #Require As

なるほど〜

gem 'rubocop'は、gem 'rubocop' require: 'rubocop'gem 'rubocop' require: trueと同じだったのか!

で、引用の前半部分。

requireにファイル名の配列かtrue(ファイル名がGem名と同じ場合)を渡すことで、Bundler.requireで自動読み込みするファイルを Gem ごとに指定できると書いてある。自動読み込みしないようにするにはfalseを渡す。

やっぱり自動読み込みしてくれるっぽい。でもBundler.requireなんて書いた覚えはない…。Rails のことだから自動でやってくれてるのかな?

これもドキュメントに書いてあった。

Bundler makes sure that Ruby can find all of the gems in the Gemfile (and all of their dependencies). If your app is a Rails app, your default application already has the code necessary to invoke bundler.
For another kind of application (such as a Sinatra application), you will need to set up bundler before trying to require any gems.

Bundler: How to use Bundler with Ruby #Setting Up Your Application to Use Bundler

前半を訳してみるとこんな感じだと思う。

「Bundler は、Gemfile の中のすべての Gem(とそれが依存するもの全部)を Ruby が見つけられるようにします。Rails アプリならデフォルトで Bundler を呼び出すのに必要なコードが含まれています。」

やっぱり!!さすが Rails

Sinatra アプリなどで、Gemfile 内の全Gem を自動読み込みさせる設定は以下とのこと。

require 'rubygems'
require 'bundler/setup'
Bundler.require(:default)

手元の Rails アプリのコードをよく見たら、ちゃんと書いてあった。


さて、ようやく本題。

require: falseを指定すると、自動読み込みしないようにする。

Rubocop は通常コマンドで使用するもので、Rails アプリの中から Rubocop のメソッドを呼び出すことはない。ということは自動読み込みさせる必要がないので、require: falseにすればよいということ。