File.expand_path("../../Gemfile", __FILE__) 这是怎么工作的?文件在哪里? [英] File.expand_path("../../Gemfile", __FILE__) How does this work? Where is the file?

查看:66
本文介绍了File.expand_path("../../Gemfile", __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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆