はじめに
なにも考えずに、ruby で require
してますんで LoadError (cannot load such file -- your_ruby_file_here)
となった時の話でも書こうと思います
今回のケース
Rubyのバージョン
$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
このようなフォルダ構成のケースです
$ tree
.
├── module.rb
└── sub_modules
├── sub_module_a.rb
├── sub_module_b.rb
└── sub_module_c.rb
require 'sub_modules/sub_module_a'
require 'sub_modules/sub_module_b'
require 'sub_modules/sub_module_c'
module MainModule
Version = "2.3.0"
end
module SubModuleA
Version = "1.0.0"
end
require
この状況でmodule.rb
をmainからロードしようとするとエラーになることがあります
irb(main):004:0> require 'module'
Traceback (most recent call last):
7: from /Users/masaino/.rbenv/versions/2.7.1/bin/irb:23:in `<main>'
6: from /Users/masaino/.rbenv/versions/2.7.1/bin/irb:23:in `load'
5: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
4: from (irb):3
3: from (irb):4:in `rescue in irb_binding'
2: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
1: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
LoadError (cannot load such file -- module)
これは、require
が参照している$LOAD_PATH
にカレントディレクトリがはいっていないからmodule.rb
がみつけられないということのようです。なので./
をつけて以下のようにしてみます
irb(main):006:0> require './module'
Traceback (most recent call last):
10: from /Users/masaino/.rbenv/versions/2.7.1/bin/irb:23:in `<main>'
9: from /Users/masaino/.rbenv/versions/2.7.1/bin/irb:23:in `load'
8: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
7: from (irb):5
6: from (irb):6:in `rescue in irb_binding'
5: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
4: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
3: from /Users/masaino/load_path/module.rb:1:in `<top (required)>'
2: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
1: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
LoadError (cannot load such file -- sub_module_a)
エラーメッセージがLoadError (cannot load such file -- sub_module_a)
に変わりました。module
自体はロードできているが、今回のケースではmodule.rb
がさらにsub_module
をrequire
しているので、そこでこけているようです。
require_relative
「現在のファイルからの相対パスで require する」ものとしてrequire_relative
もありますが、結果は同じです。
irb(main):005:0> require_relative 'module'
Traceback (most recent call last):
9: from /Users/masaino/.rbenv/versions/2.7.1/bin/irb:23:in `<main>'
8: from /Users/masaino/.rbenv/versions/2.7.1/bin/irb:23:in `load'
7: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
6: from (irb):4
5: from (irb):5:in `rescue in irb_binding'
4: from (irb):5:in `require_relative'
3: from /Users/masaino/load_path/module.rb:1:in `<top (required)>'
2: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
1: from /Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
LoadError (cannot load such file -- sub_module_a)
$LOAD_PATH
ということで、素直に$LOAD_PATH
にカレントディレクトリを設定した方が良さそうです。そもそも今の$LOAD_PATH
はどうなってるんだ?
irb(main):001:0> puts $LOAD_PATH
/usr/local/Cellar/rbenv/1.1.2/rbenv.d/exec/gem-rehash
/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/site_ruby/2.7.0
/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/site_ruby/2.7.0/x86_64-darwin19
/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/site_ruby
/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/vendor_ruby/2.7.0
/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/vendor_ruby/2.7.0/x86_64-darwin19
/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/vendor_ruby
/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0
/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0/x86_64-darwin19
=> nil
確かにカレントディレクトリはないので追加してみます
irb(main):002:0> $LOAD_PATH.push('.')
=> ["/usr/local/Cellar/rbenv/1.1.2/rbenv.d/exec/gem-rehash", "/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/site_ruby/2.7.0", "/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/site_ruby/2.7.0/x86_64-darwin19", "/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/site_ruby", "/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/vendor_ruby/2.7.0", "/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/vendor_ruby/2.7.0/x86_64-darwin19", "/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/vendor_ruby", "/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0", "/Users/masaino/.rbenv/versions/2.7.1/lib/ruby/2.7.0/x86_64-darwin19", "."]
再度、ロードしてみると、いけました
irb(main):006:0> require 'module'
=> true
irb(main):003:0> MainModule::Version
=> "2.3.0"
irb(main):004:0> SubModuleA::Version
=> "1.0.0"
RUBYLIB
を使う方法
RUBYLIB
を export しておく方法でもいけます(指定したパスがサーチパスに追加される)
$ RUBYLIB=.
$ export RUBYLIB