Rubyのrequire

疑問

ruby では require でライブラリを読む。 (ファイルは .rb (rubyファイル)でも .so 等でもよいようだ)

参照するパスは $: (or $LOAD_PATH) が使われる。

gem でインストールすると ~/.gem/ にインストールされる。 gem install rufo で rufo をインストールしたあとパスを確認すると以下の通り。

$ gem which rufo
/home/XXXX/.gem/ruby/2.6.0/gems/rufo-0.12.0/lib/rufo.rb

この状態で require "rufo" をするとエラーが出ないから、ライブラリ読み込みは成功している。しかし、 $: に ~/.gem は入ってない。なぜ require できるのか。

$ ruby -e 'require "rufo"'
$ ruby -e 'puts $:'
/usr/share/gems/gems/did_you_mean-1.2.2/lib
/usr/local/share/ruby/site_ruby
/usr/local/lib/ruby/site_ruby/2.6
/usr/share/ruby/vendor_ruby
/usr/lib/ruby/vendor_ruby/2.6
/usr/share/rubygems
/usr/share/ruby/2.6
/usr/lib/ruby/2.6

答え

rubygem が require を書き換えているらしい。

https://medium.com/@connorstack/understanding-ruby-load-require-gems-bundler-and-rails-autoloading-from-the-bottom-up-3b422902ca0

確かに require した後に $: を見ると ~/.gem が追加されている。

$ ruby -e 'require "rufo"; puts $:'
/usr/share/gems/gems/did_you_mean-1.2.2/lib
/home/XXX/.gem/ruby/2.6.0/gems/rufo-0.12.0/lib
/usr/local/share/ruby/site_ruby
/usr/local/lib/ruby/site_ruby/2.6
/usr/share/ruby/vendor_ruby
/usr/lib/ruby/vendor_ruby/2.6
/usr/share/rubygems
/usr/share/ruby/2.6
/usr/lib/ruby/2.6