Ruby:需要在gem中工作,从源

时间:2017-04-20 15:19:33

标签: ruby rubygems require directory-structure code-structure

尝试根据bundler's official guide on developing a Ruby gem创建一个gem。

运行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>'

另一方面,通过rake install安装宝石,然后要求宝石工作正常。

如果foodie.rb中的require "foodie/version"更改为require_relative "foodie/version",则可以从源代码处理。据我了解

  • require基于模块工作
  • require_relative基于目录结构工作

对我来说,后者看起来像个黑客。通过模块构建代码不再有意义,因为它不会被强制执行(可能它仍然有意义,但你可能会犯错并且从不注意)。

我的问题是:

  • 是否可以在遵循捆绑程序约定(使用require而不是require_relative)的同时安装来自源代码的宝石?
  • 安装后为什么宝石有效?
  • 是否有使用requirerequire_relative,模块,文件和一般结构的最佳做法?

谢谢。

1 个答案:

答案 0 :(得分:1)

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

你说“据我所知...... require基于模块工作”,这是不正确的。 require与文件一起工作,只是通常在具有匹配名称的文件中定义类或模块,例如MyModule可能在my_module.rb

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

$ ruby -I lib lib/foodie.rb

如果您想避免输入-I lib,可以使用RUBYLIB环境变量。 Ruby将其内容添加到加载路径:

$ export RUBYLIB=lib
$ ruby lib/foodie.rb

(在Windows上,我认为您需要使用set而不是export。)

您还可以通过程序本身来操纵加载路径。它存储在全局变量$LOAD_PATH中,别名为:$。这就是Rubygems和Bundler管理宝石的方式。