在ruby中需要一个目录中的所有文件的最佳方法是什么?
在ruby中,从一个目录中获取所有文件的最佳方法是什么?如何:在ruby中需要一个目录中的所有文件的最佳方法是什么?,ruby,file,directory,require,Ruby,File,Directory,Require,在ruby中,从一个目录中获取所有文件的最佳方法是什么?如何: Dir["/path/to/directory/*.rb"].each {|file| require file } 如果它是与执行所需操作的文件相关的目录(例如,您希望加载lib目录中的所有文件): 编辑:根据以下评论,更新版本: Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file } 最好的方法是将目录添加到加载路径,然后require每个文件的
Dir["/path/to/directory/*.rb"].each {|file| require file }
如果它是与执行所需操作的文件相关的目录(例如,您希望加载lib目录中的所有文件): 编辑:根据以下评论,更新版本:
Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file }
最好的方法是将目录添加到加载路径,然后
require
每个文件的基本名称。这是因为您希望避免意外地需要相同的文件两次——通常不是预期的行为。是否加载文件取决于require
以前是否看到传递给它的路径。例如,这个简单的irb会话表明,您可能会错误地要求并加载同一个文件两次
$ irb
irb(main):001:0> require 'test'
=> true
irb(main):002:0> require './test'
=> true
irb(main):003:0> require './test.rb'
=> false
irb(main):004:0> require 'test'
=> false
请注意,前两行返回true
,这意味着两次都加载了相同的文件。使用路径时,即使路径指向同一位置,require
也不知道该文件已经是必需的
在这里,我们向加载路径添加一个目录,然后需要其中每个*.rb文件的basename
dir = "/path/to/directory"
$LOAD_PATH.unshift(dir)
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }
如果您不关心多次需要该文件,或者您只是想加载该文件的内容,那么可能应该使用load
而不是require
。在这种情况下使用load,因为它可以更好地表达您要完成的任务。例如:
Dir["/path/to/directory/*.rb"].each {|file| load file }
请尝试“需要所有宝石”: 它让您可以简单地:
require_all 'path/to/directory'
如果不剥离扩展名,那么可能需要两次相同的文件(ruby不会意识到“foo”和“foo.rb”是同一个文件)。要求同一文件两次可能导致虚假警告(例如,“警告:已初始化常量”)
这将在本地机器和不使用相对路径的远程机器(如Heroku)上递归工作
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))
或者,如果要确定要加载到特定文件夹的文件的范围,请执行以下操作:
Dir.glob(File.join('path', '{folder1,folder2}', '**', '*.rb'), &method(:require))
说明:
将块作为参数
方法(:require)
&方法(:require)将方法转换为一个bloc。我使用
文件,而不是像某些答案中那样连接路径。展开\u path
:
Dir[File.expand_path('importers/*.rb', File.dirname(__FILE__))].each do |file|
require file
end
更新:
您可以执行以下操作,而不是使用File.dirname
:
Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
require file
end
其中,
。
删除了\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
Dir[Rails.root.join*%w(应用工作者关注*)]。在Rails中,每个{f | require f}
都可以执行以下操作:
Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
更新:建议@Jiggneshh Gohel删除斜杠,已更正。关于:要求相对路径['relative path']
?根据鹤嘴锄,扩展名.rb是可选的。从技术上讲,它改变了含义:“require'foo.rb'”需要foo.rb,而“require'foo'”可能需要foo.rb、foo.so或foo.dll。不剥离扩展有一个微妙的窍门。如果代码调用的其他部分需要'foo',ruby将再次加载相同的文件,这可能会导致错误。我添加了我自己的答案,解释了这一点,并展示了如何剥离扩展。@Pete,这仍然是真的吗?请参见下文。这可能是显而易见的,但值得注意的是,删除.rb还需要dir中的任何非.rb文件,这可能是不需要的。@PeteHodgson的建议不准确。Ruby的require
没有被.rb
扩展的存在与否所混淆。在MRI 1.8.7-p374、2.1.5和2.2.0上测试。这个城市传奇来自Rails,在Rails中,“聪明”的自动加载展示了他在旧版本中描述的行为(现在可能仍在展示)。真的是这样吗?文档说明:如果某个功能的名称已出现在$”中,则不会加载该功能。该文件名已转换为绝对路径,因此“需要'A';require'./a''不会加载a.rb两次。我的测试显示与Derek所说的相同:require“foo.rb”;require“foo”";
只会加载一次foo.rb
。@PeteHodgson-你能备份一下吗?不行。Ruby的require
不会被.rb
扩展的存在与否所混淆。在MRI 1.8.7-p374、2.1.5和2.2.0上测试。这个城市传奇来自Rails,“聪明”的自动加载展示了旧版本中描述的行为(现在可能仍在展示)。我需要包括我的所有ActiveRecord模型,require_all gem计算出了所有依赖项,并且完美地要求它们。谢谢@panupan只需注意,require\u all
的循环依赖项解析解决了源代码中的一个问题:您有不需要依赖项的Ruby源文件。这将关闭手术刀加载的门,使您承担全部或全部加载任务。这在小型库中不是问题,但这是一个你应该有意识地做出的决定。用你可以简单地用一行代码替换的宝石来填充你的应用程序是没有意义的。这会增加应用程序的加载时间,并长期导致更多错误。您还可以添加所有子目录,如Dir[File.dirname(\uu File\uu)+'/support/***.rb']。每个{124; File | require File}
使用File.join可能比假设向前/向后斜杠更安全:Dir[File.join(File.dirname(|FILE|uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
@maasha您如何使用require\u relative
来要求目录中的所有文件?这是一些漂亮的代码。我喜欢没有可见块的方式。Dir.glob(File.join(File.dirname(\uu File\uuuu))、“{lib,addons}”、“subfolder”、“**”、“*.rb”)和方法(:require))
消除了对
Dir[File.expand_path('importers/*.rb', File.dirname(__FILE__))].each do |file|
require file
end
Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
require file
end
Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }