更改$ LOAD_PATH时,为什么要使用unshift而不是push?

时间:2014-01-21 09:03:33

标签: ruby

我发现ruby加载路径是一个数组,许多项目使用它如下:

 $:.unshift(File.expand_path("../../lib", __FILE__))

它可以将本地文件添加到ruby路径数组的前面,以便我们可以使用或加载。

所以,我希望知道为什么我们不使用push在数组的末尾添加文件?

2 个答案:

答案 0 :(得分:10)

假设您有一个“date.rb”文件(为什么不),并且您想要加载此文件,而不是标准库日期。

如果您使用追加,则在致电require 'date'时永远不会加载您的文件,因为它位于数组的末尾,并且之前会找到标准日期。

因此,如果您将路径添加到加载路径之前,则不会冒优先级查找的风险

答案 1 :(得分:2)

这是因为concat是将一个数组添加到另一个数组。使用unshift,您可以将任何项目添加到列表的开头。并且在加载路径的情况下,顺序是重要的,因此将其添加到开头是重要的,因此例如铲子<<(),将项目添加到最后,是不够的:

["a", "b"].concat(["c", "d"]) #=>  ["a", "b", "c", "d"]
["a", "b"].unshift("c").unshift("d") #=> ["d", "c", "a", "b"]
["a", "b"] << "c" << "d" #=>  ["a", "b", "c", "d"]

首先,获取lib目录:

File.expand_path("../../lib", __FILE__)
#=> "/home/foo/lib/" #Note this is a string!

然后将其添加到包含当前加载路径的$:.。例如:

 $:.
 #=> ["/usr/local/lib/site_ruby/1.9.1", "/usr/lib/ruby/1.9.1/i686-linux"]

通过取消它,将它添加到加载路径列表的开头:

 $:.unshift(File.expand_path("../../lib", __FILE__))
 #=> ["/home/foo/lib", "/usr/local/lib/site_ruby/1.9.1", "/usr/lib/ruby/1.9.1/i686-linux"]

然而,concat不仅会将它添加到最后,还需要一些额外的丑陋语法,[]围绕字符串将其作为项目中的项目传递:

  $:.concat([File.expand_path("../../lib", __FILE__)])
  #=> ["/usr/local/lib/site_ruby/1.9.1", "/usr/lib/ruby/1.9.1/i686-linux", "/home/lib"]