Ruby:require在gem中工作,从源代码运行时失败

Ruby:require在gem中工作,从源代码运行时失败,ruby,rubygems,require,directory-structure,code-structure,Ruby,Rubygems,Require,Directory Structure,Code Structure,尝试创建一个宝石的基础上 运行bundle gem foodie将在lib目录中创建一个结构并生成文件: 美食家 version.rb foodie.rb foodie.rb阅读 require "foodie/version" module Foodie # Your code goes here... end 运行ruby lib/foodie.rb(或从不同目录运行)将导致 C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/ker

尝试创建一个宝石的基础上

运行
bundle gem foodie
将在
lib
目录中创建一个结构并生成文件:

  • 美食家
    • version.rb
  • foodie.rb
foodie.rb阅读

require "foodie/version"

module Foodie
  # Your code goes here...
end
运行ruby lib/foodie.rb(或从不同目录运行)将导致

C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- foodie/versio
n (LoadError)
        from C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from foodie.rb:1:in `<main>'
C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core\u ext/kernel\u require.rb:55:在'require'中:无法加载这样的文件--foodie/versio
n(加载错误)
来自C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core\u ext/kernel\u require.rb:55:in'require'
来自foodie.rb:1:in`'
另一方面,通过rake install安装gem,然后需要gem就可以了

如果foodie.rb中的
require“foodie/version”
更改为
require\u relative“foodie/version”
,则它可以从源代码开始工作。据我所知

  • require
    基于模块工作
  • require\u relative
    基于目录结构工作
在我看来,后者就像一个黑客。通过模块来构造代码不再有意义,因为它不会被强制执行(也许它仍然有意义,但您可能会犯错误,并且永远不会注意到)

我的问题是:

  • 在遵循bundler约定(使用
    require
    而不是
    require\u relative
    )的情况下,是否可以从源代码测试gem而不安装它
  • 为什么gem在安装后还能工作
  • 使用
    require
    require\u relative
    、模块、文件和一般结构是否有最佳实践

谢谢。

您需要将
lib
dir添加到Ruby的加载路径中。加载路径是Ruby在调用
require
时搜索文件的目录列表。Rubygems还管理使用gem时的加载路径,这就是为什么作为gem安装时代码可以工作的原因

你说“据我所知…
require
基于模块工作”,这是不正确的
require
可以处理文件,按照惯例,类或模块是用匹配的名称在文件中定义的,例如,
MyModule
可能位于
my_module.rb

有几种方法可以将dir添加到加载路径。在命令行中,您可以使用
-I
选项:

$ruby-I lib/foodie.rb
如果要避免键入
-I lib
,可以使用
RUBYLIB
环境变量。Ruby将其内容添加到加载路径:

$export RUBYLIB=lib
$ruby lib/foodie.rb
(在Windows上,我认为您需要使用
set
而不是
export


您还可以使用程序本身操纵加载路径。它存储在全局变量
$LOAD\u PATH
中,别名为
:$
。这是Rubygems和Bundler管理您的gems的方式。

请将其分成几个单独的问题,因为:1。你问的三个问题完全不同,答案是2。这样对未来的读者会更有用。谢谢谢谢你的反馈。我这样问是因为这些问题来自同一个问题/背景——我想象其他人在类似的情况下也会有类似的问题。我认为每个问题都需要相同的背景。对几个问题重复相同的上下文是一种好的做法吗?谢谢!两个备注/问题:1,我的假设是,即使您在一个文件中定义了多个模块和类,您也可以选择只需要某个类(例如,
要求在单个文件中使用以下结构的a/B/C
模块a模块B类C…end
)。难道没有办法做到这一点吗?2.对我来说,
require\u relative
require
相同,只是前者具有扩展的功能,因此应优先考虑。您是否同意这一点,或者一般使用
require\u relative
而不是
require
有什么缺点?