为什么相对路径在Ruby中不起作用

我开始学习Ruby,有一点我不明白,为什么require指令的相对路径在ruby中不起作用。 它几乎适用于我现在的每种脚本语言(JSP,PHP ……)。 我用一个真实的例子来解释。 我有一个名为shapes的文件夹,其中包含3个类形状矩形方形 。 我还有另一个文件test_shapes.rb,我调用并测试我的类。 当我将类导入到主文件时,如下所示:

require "./shape" require "./rectangle" require "./square" 

我找不到找不到的文件的错误。 当我包含我的子文件夹的名称时,如下所示:

 require "./shapes/shape" require "./shapes/rectangle" require "./shapes/square" 

代码完美无缺。 因为我指定了项目根目录的整个路径(我认为是lib文件夹)。 当我包括我包括硬盘的绝对路径,如下所示:

 require "#{File.dirname(__FILE__)}/shape" require "#{File.dirname(__FILE__)}/rectangle" require "#{File.dirname(__FILE__)}/square" 

它也很完美。

所以,我只是想要一些解释,如果知道为什么第一个导入方法(当前文件夹的相对路径)不起作用。

相对路径基于工作目录。 我假设同一目录中有主文件。 如果你在项目根目录上运行ruby ./shapes/main.rb尝试查找{project_root}/shape.rb ,而不是{project_root}/shapes/shape.rb 。 它不起作用。

您需要使用require_relative如下所示。

 # {project_root}/shapes/main.rb require_relative './shape' require_relative './rectangle' require_relative './square' 

你正在使用相对路径。 它们与脚本执行的位置相关。 一般来说这是个坏主意。 您应该使用绝对路径,或者执行require精确文件的相对路径。

 require File.expand_path("../shape", __FILE__) 

PS: require_relative看起来更简洁

require(name)→true或false加载给定名称,如果成功则返回true,如果已加载该function则返回false。

如果文件名未解析为绝对路径,则将在$ LOAD_PATH($ :)中列出的目录中搜索它。

如果文件名的扩展名为“.rb”,则将其作为源文件加载; 如果扩展名是“.so”,“。o”或“.dll”,或者是当前平台上的默认共享库扩展,Ruby会将共享库作为Ruby扩展加载。 否则,Ruby会尝试将“.rb”,“。so”等添加到名称中,直到找到。 如果找不到名为的文件,则会引发LoadError。

对于Ruby扩展,给定的文件名可以使用任何共享库扩展。 例如,在Linux上,套接字扩展名为“socket.so”,并且要求“socket.dll”将加载套接字扩展名。

加载文件的绝对路径被添加到$ LOADED_FEATURES($“)。如果文件的路径已经出现在$”中,则不会再次加载文件。 例如,要求’a’; 要求’./a’不会再次加载a.rb。

require“my-library.rb”require“db-driver”加载的源文件中的任何常量或全局变量都将在调用程序的全局命名空间中可用。 但是,局部变量不会传播到加载环境。

require_relative(string)→true或false Ruby尝试相对于require文件的路径加载名为string的库。 如果无法确定文件的路径,则引发LoadError。 如果加载文件,则返回true,否则返回false。

参考: http : //ruby-doc.org/core-2.1.2/Kernel.html#require-method