尝试根据bundler's official guide on developing a Ruby gem创建一个gem。
运行bundle gem foodie
将在lib
目录中创建一个结构并生成文件:
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
)的同时安装来自源代码的宝石?require
,require_relative
,模块,文件和一般结构的最佳做法?谢谢。
答案 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管理宝石的方式。