File.expand_path如何工作?

时间:2016-12-17 03:48:58

标签: ruby

我不确定我是否了解File.expand_path执行操作的顺序。以下是pry会话示例:

[1] pry(main)> File.expand_path('.')
=> "/Users/max/Dropbox/work/src/github.com/mbigras/foobie"
[2] pry(main)> File.expand_path('..')
=> "/Users/max/Dropbox/work/src/github.com/mbigras"
[3] pry(main)> File.expand_path('..', "cats")
=> "/Users/max/Dropbox/work/src/github.com/mbigras/foobie"
[4] pry(main)> File.expand_path('..', __FILE__)
=> "/Users/max/Dropbox/work/src/github.com/mbigras/foobie"
[5] pry(main)> File.expand_path('../lib', __FILE__)
=> "/Users/max/Dropbox/work/src/github.com/mbigras/foobie/lib"
[7] pry(main)> File.expand_path('./lib')
=> "/Users/max/Dropbox/work/src/github.com/mbigras/foobie/lib"
[8] pry(main)> File.expand_path('./lib', __FILE__)
=> "/Users/max/Dropbox/work/src/github.com/mbigras/foobie/(pry)/lib"
[9] pry(main)>

[1]有道理,我正在扩展当前工作目录的路径。

[2]有道理,我正在扩展cwd的父目录的路径

[3]没有意义,我接受阅读another answer,由于某种原因,ruby隐含地接受了第二个arg的File.dirnameFile.dirname('cats')的情况它会扩展为cwd .,因为'cats'不是嵌套的。但那么为什么File.expand_path('..', '.')没有相同的结果?

[18] pry(main)> File.expand_path('..', 'cats')
=> "/Users/max/Dropbox/work/src/github.com/mbigras/foobie"
[19] pry(main)> File.dirname('cats')
=> "."
[20] pry(main)> File.expand_path('..', '.')
=> "/Users/max/Dropbox/work/src/github.com/mbigras"

[4]没有意义,但原因与[3]相同。在这种情况下,“随机字符串”是"(pry)",因为p __FILE__ #=> "(pry)"在撬开会话中。

[5]没有意义,为什么File.expand_path会去看似无人的父目录,然后神奇地回到cwd并决定进入lib

[7]有道理,但无法帮助我理解[5]

[8]没有意义,为什么“随机字符串”现在楔入cwd .lib

之间

来自文档:

File.expand_path("../../lib/mygem.rb", __FILE__)
#=> ".../path/to/project/lib/mygem.rb"
  

首先它解析__FILE__的父,即bin /,然后转到父项,项目的根,并附加lib / mygem.rb。

操作顺序并没有真正加起来。

  1. 选择File.dirname(__FILE__)
  2. 转到作为根
  3. 的父级
  4. 追加lib / mygem.rb
  5. 步骤2和3没有帮助。我们为什么要去父母?为什么我们甚至首先做第1步?为什么有../..?这是不是意味着从当前工作目录升级两级?

    会喜欢一些指导原则来理解这些例子。

    编辑以添加黄金:

      

    File.expand_path转到第二个参数指定的目录中的第一个参数(Dir.pwd,如果不存在)。 - Eric Duminil

1 个答案:

答案 0 :(得分:1)

理论

我认为您在阅读链接的答案时错过了..

File.dirname

完全没有明确expand_path。{/ 1}
File.expand_path('../../Gemfile', __FILE__)
#                 ^^ Note the difference between here and
#                 vv there
File.expand_path('../Gemfile', File.dirname(__FILE__))

首先让我感到困惑的是,第二个参数始终被File.expand_path视为目录,即使它不存在,即使它看起来像文件,或者即使它是一个文件现有文件。

File.expand_path转到第二个参数指定的目录中的第一个参数(Dir.pwd,如果不存在)。

实施例

[3]

File.expand_path('..', "cats")

它在当前目录中执行,即"/Users/max/Dropbox/work/src/github.com/mbigras/foobie"

cats是现有文件,现有目录还是不存在的目录?

File.expand_path并不重要:"cats"被视为现有目录,File.expand_path在其中开始。

此命令相当于启动:

File.expand_path('..')

"/Users/max/Dropbox/work/src/github.com/mbigras/foobie/cats"目录中。

所以expand_path返回一个目录,然后返回:

"/Users/max/Dropbox/work/src/github.com/mbigras/foobie"

[4]

同样的事情。它相当于(可能)不存在的File.expand_path('..')

"/Users/max/Dropbox/work/src/github.com/mbigras/foobie/(pry)"

所以它是:

"/Users/max/Dropbox/work/src/github.com/mbigras/foobie"

[5]

从[4]开始,它只是转到子文件夹lib

[8]

"/Users/max/Dropbox/work/src/github.com/mbigras/foobie/(pry)"开始 ,它只是转到子文件夹lib

再次,File.expand_path永远不会检查相应的文件夹和子文件夹是否存在。