File.expand_path(“../../ Gemfile”,__FILE__)这是如何工作的? 档案在哪里?
ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
我只是试图从某个目录访问一个.rb文件,一个教程告诉我要使用这个代码,但是我不知道它是如何find这个gem文件的。
File.expand_path('../../Gemfile', __FILE__)
当你知道相对于当前文件的path时,获取文件的绝对path是一个有点丑陋的Ruby成语。 另一种书写方式是这样的:
File.expand_path('../Gemfile', File.dirname(__FILE__))
两者都很丑,但是第一个变种更短。 然而,第一个变体在你掌握之前也是非常不直观的。 为什么额外..
? (但第二个变体可能会提供一个线索,说明为什么需要)。
这是如何工作的: File.expand_path
返回第一个参数相对于第二个参数(默认为当前工作目录)的绝对path。 __FILE__
是代码所在文件的path。由于本例中的第二个参数是一个文件的path,而File.expand_path
假定了一个目录,所以我们必须在path中添加一个额外的..
以获得正确的path。 这是如何工作的:
File.expand_path
基本上是这样实现的(在下面的代码path
中将具有../../Gemfile
的值,而relative_to
的值将是/path/to/file.rb
):
def File.expand_path(path, relative_to=Dir.getwd) # first the two arguments are concatenated, with the second argument first absolute_path = File.join(relative_to, path) while absolute_path.include?('..') # remove the first occurrence of /<something>/.. absolute_path = absolute_path.sub(%r{/[^/]+/\.\.}, '') end absolute_path end
(还有一点点,它扩展到主目录等 – 上面的代码可能还有一些其他问题)
通过调用absolute_path
上面的代码,将首先获取/path/to/file.rb/../../Gemfile
值,然后对于循环中的每一轮,将删除第一个..
以及path组件之前。 先删除/file.rb/..
,然后在下一轮/to/..
被删除,我们得到/path/Gemfile
。
长话短说,当知道相对于当前文件的path时, File.expand_path('../../Gemfile', __FILE__)
是获取文件绝对path的技巧。 在相对path中的额外的是消除__FILE__
文件的名称。
两个参考:
- File :: expand_path方法文档
-
__FILE__
如何在Ruby中工作
今天我偶然发现了这个:
boot.rb提交在Rails的Github
如果从目录树中的boot.rb中find两个目录:
/ railties / lib目录/导轨/发电机/导轨/应用/模板
你会看到Gemfile,这导致我相信File.expand_path("../../Gemfile", __FILE__)
引用下面的文件: /path/to/this/file/../../Gemfile
File.expand_path("../../Gemfile", __FILE__)
/path/to/this/file/../../Gemfile
file File.expand_path("../../Gemfile", __FILE__)