不能从主文件以外的目录中获取 ruby 文件 (LoadError)

Cannot require ruby files from a directory other then the one with main files (LoadError)

我的问题如下:

除了包含所有主要文件的目录之外,我不能从任何目录中要求 ruby 文件,即 require 像这样:./file 工作正常,但是 require像这样:dir_name/file 失败。

这是我的项目结构:

├── bin
│   ├── console
│   └── setup
├── CODE_OF_CONDUCT.md
├── Gemfile
├── lib
│   ├── riverbattle
│   │   ├── base.rb          <------- main file that starts everything
│   │   ├── colorful.rb
│   │   ├── computer.rb
│   │   ├── constants.rb
│   │   ├── exit_error.rb
│   │   ├── field.rb
│   │   ├── game.rb
│   │   ├── human.rb
│   │   ├── invalid_move_error.rb
│   │   ├── move.rb
│   │   ├── player.rb
│   │   ├── version.rb
│   │   └── victory_error.rb
│   └── riverbattle.rb  <------ the file from where I get the error
├── LICENSE
├── LICENSE.txt
├── Rakefile
├── README.md
├── spec
│   ├── spec_helper.rb
│   └── riverbattle_spec.rb
├── riverbattle-0.1.2.gem
└── riverbattle.gemspec

所以,当我像这样启动应用程序时: ruby base.rb 当我在 lib/riverbattle/ 目录中时,一切都正常启动,但是当我尝试从目录中执行 ruby riverbattle.rb lib/,我收到以下错误:

➜ lib git:(master) ✗ ruby riverbattle.rb /home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in require': cannot load such file -- ./field (LoadError) from /home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:inrequire' from /home/denis/.rvm/gems/ruby-2.2.1/gems/riverbattle-0.1.2/lib/riverbattle/game.rb:1:in <top (required)>' from /home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:inrequire' from /home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in require' from /home/denis/.rvm/gems/ruby-2.2.1/gems/riverbattle-0.1.2/lib/riverbattle/base.rb:1:in ' from /home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in require' from /home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:inrequire' from riverbattle.rb:2:in `'

我只是不明白为什么它不能要求一个文件。 顺便说一句,这是我从中得到错误的文件 (riverbattle.rb) 的内容:

require "riverbattle/version"

module Riverbattle
  require "riverbattle/base"
end

仅此而已。

我被告知 require 实际上需要文件的绝对路径,我需要用我的 $LOAD_PATH 或其他东西做点什么,但这些信息对解决问题根本没有帮助问题。为什么可以从同一目录中获取文件,但如果我从另一个目录中获取文件就不行了?


1) 谁能帮我解决这个问题?

2) 是否只有我的电脑有问题,我可以安全地将它发布为 gem(即它可能在另一台电脑上正常工作),或者是错误的代码不起作用?

require 在您的 $LOAD_PATH 中搜索。如果您想使用系统上安装的 gem,通常应使用 require。为了您的目的,您要使用 require_relative:

require_relative 'riverbattle/version'

注意乍一看

require './riverbattle/version'

似乎也可行。但是,这里的.指向的是你运行进程所在的当前目录,而不是文件所在的目录,显然这不是你想要的。

如果 lib/base.rb 是您的主文件,那么也许它应该是 "executable" 文件?如果是这样,它应该在 bin 中吗?

$LOAD_PATH 可以通过对 ruby 可执行文件使用 -I 选项来添加。

ruby -Ipath_to_project_root/lib lib/main.rb

然后会让任何需要项目中文件的文件在 lib 文件夹中查找。

它也可以像 中的答案一样与 $:$LOAD_PATH 一起使用。

看看其他 gem 是如何设置的,您会发现您的 base.rb 文件可以放在 bin 文件夹中,就像您的设置和控制台文件一样。如果它是启动它的主脚本,它可以被命名为 riverbattle 就像 gems 一样具有相同或相似名称的可执行文件。

require 不用于加载 gems,它用于加载文件并且没有给出任何显式路径,将在加载路径中查找。是不是gem都没关系。

require_relative用于加载相对于使用require_relative方法的文件总是本地的文件。

当然,documentation是你的朋友。