我正在写一个Ruby宝石。在lib / my_gem.rb根文件中,我有这个文件:
require_relative "my_gem/practices/practice"
但是该文件Practice.rb要求Practices /目录中多个子目录中的多个* .rb文件。因此,在文件底部,我这样做:
Dir["#{Dir.pwd}/lib/my_gem/practices/**/*.rb"].each do |file|
require file
end
它可以工作,但是当我查看其他宝石(如Rails)时,我发现它们从未使用过Dir.pwd
。还有另一种方法可以做到这一点吗?
答案 0 :(得分:0)
如果依赖性仅是这样:文件A需要文件B,文件B需要文件C,则文件A不应该处理文件C。文件C的要求应该写在文件B上,而不是文件A上
对于您而言,要求将子目录中的*.rb
文件写入practice.rb
中,而不是lib/my_gem.rb
中。
答案 1 :(得分:0)
require
尝试在$LOAD_PATH
中每个目录的上下文中加载相对文件规范。当require
被指定为gem时,其lib目录将添加到该加载路径。这样可以使用require
代替require_relative
。例如,在我的rails控制台中,我看到此输出包含在puts $LOAD_PATH
的输出中:
/Users/kbennett/.rvm/gems/ruby-2.5.1/gems/rack-2.0.5/lib
/Users/kbennett/.rvm/gems/ruby-2.5.1/gems/rails-html-sanitizer-1.0.4/lib
/Users/kbennett/.rvm/gems/ruby-2.5.1/gems/loofah-2.2.2/lib
在您的情况下,运行代码时不需要使用gem。因此,您需要使用require_relative
或将lib目录显式添加到加载路径。我更喜欢前一种方法;对我来说更干净。
使用File.dirname
,File.join
和__FILE__
,您可以计算要从中构建文件规范的目录并传递到require
。您也可以使用Dir.pwd
,但是如果从其他目录运行代码,则会中断。
因此,在您的my_gem.rb中,您可以使用下面的代码(通常我不会使用那么多的中间变量,但它们在此处出于说明目的很有用):
this_dir = File.dirname(__FILE__)
rb_filemask = File.join(this_dir, 'practices/**/*.rb')
rb_files = Dir[rb_filemask]
rb_files.each { |filespec| require filespec }