File.expand_path("../../Gemfile", __FILE__) 这是怎么工作的?文件在哪里? [英] File.expand_path("../../Gemfile", __FILE__) How does this work? Where is the file?
问题描述
ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
我只是想从某个目录访问一个 .rb 文件,一个教程告诉我使用此代码,但我不知道它是如何找到 gem 文件的.
I'm just trying to access a .rb file from the some directory and a tutorial is telling me to use this code but I don't see how it is finding the gem file.
推荐答案
File.expand_path('../../Gemfile', __FILE__)
是一个有点丑陋的 Ruby 习惯用法,用于在您知道相对于当前文件的路径时获取文件的绝对路径.另一种写法是这样的:
is a somewhat ugly Ruby idiom for getting the absolute path to a file when you know the path relative to the current file. Another way of writing it is this:
File.expand_path('../Gemfile', File.dirname(__FILE__))
两者都很丑,但第一个变体更短.但是,在您掌握窍门之前,第一个变体也非常不直观.为什么要额外的 ..
?(但第二个变体可能会提供关于为什么需要它的线索).
both are ugly, but the first variant is shorter. The first variant is, however, also very non-intuitive until you get the hang of it. Why the extra ..
? (but the second variant may give a clue as to why it is needed).
它是这样工作的:File.expand_path
返回第一个参数的绝对路径,相对于第二个参数(默认为当前工作目录).__FILE__
是代码所在文件的路径.由于本例中的第二个参数是文件的路径,并且 File.expand_path
假设一个目录,我们有在路径中粘贴一个额外的 ..
以获得正确的路径.这是它的工作原理:
This is how it works: File.expand_path
returns the absolute path of the first argument, relative to the second argument (which defaults to the current working directory). __FILE__
is the path to the file the code is in. Since the second argument in this case is a path to a file, and File.expand_path
assumes a directory, we have to stick an extra ..
in the path to get the path right. This is how it works:
File.expand_path
基本上是这样实现的(在下面的代码中 path
将具有 ../../Gemfile
的值并且 relative_to
将具有 /path/to/file.rb
) 的值:
File.expand_path
is basically implemented like this (in the following code path
will have the value of ../../Gemfile
and relative_to
will have the value of /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
(还有一点,它将 ~
扩展到主目录等等——上面的代码可能还有一些其他问题)
(there's a little bit more to it, it expands ~
to the home directory and so on -- there are probably also some other issues with the code above)
单步执行对上述代码的调用 absolute_path
将首先获得值 /path/to/file.rb/../../Gemfile
,然后为循环中的每一轮,第一个 ..
将被删除,连同它之前的路径组件.首先 /file.rb/..
被删除,然后在下一轮 /to/..
被删除,我们得到 /path/Gemfile代码>.
Stepping through a call to the code above absolute_path
will first get the value /path/to/file.rb/../../Gemfile
, then for each round in the loop the first ..
will be removed, along with the path component before it. First /file.rb/..
is removed, then on the next round /to/..
is removed, and we get /path/Gemfile
.
长话短说,File.expand_path('../../Gemfile', __FILE__)
是在知道相对路径时获取文件绝对路径的技巧到当前文件.相对路径中多出的..
就是去掉__FILE__
中的文件名.
To make a long story short, File.expand_path('../../Gemfile', __FILE__)
is a trick to get the absolute path of a file when you know the path relative to the current file. The extra ..
in the relative path is to eliminate the name of the file in __FILE__
.
在 Ruby 2.0 中有一个名为 __dir__
的 Kernel
函数,它实现为 File.dirname(File.realpath(__FILE__))
.
In Ruby 2.0 there is a Kernel
function called __dir__
that is implemented as File.dirname(File.realpath(__FILE__))
.
这篇关于File.expand_path("../../Gemfile", __FILE__) 这是怎么工作的?文件在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!