为什么相对路径在 Ruby 中不起作用需要
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25314237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why relative path doesn't work in Ruby require
提问by Amaynut
I'm starting learning Ruby, one thing that I don't understand, why relative path for require directive doesn't work in ruby. It's something that works almost in every scripting language that I now (JSP, PHP...). I explain with a real example. I have a folder named shapeswhich contains 3 classes shape, rectangleand square. I have also another file test_shapes.rb from where I call and test my classes. When I import my classes to the main file like this:
我开始学习 Ruby,我不明白的一件事是,为什么 require 指令的相对路径在 ruby 中不起作用。它几乎适用于我现在的所有脚本语言(JSP、PHP...)。我用一个真实的例子来解释。我有一个名为shape的文件夹,其中包含 3 个类shape、rectangle和square。我还有另一个文件 test_shapes.rb ,我在那里调用和测试我的类。当我将类导入到主文件时,如下所示:
require "./shape"
require "./rectangle"
require "./square"
I got error for files not found. When I include the name of my subfolder like this:
我收到找不到文件的错误。当我像这样包含子文件夹的名称时:
require "./shapes/shape"
require "./shapes/rectangle"
require "./shapes/square"
The code is perfectly working. Because I specified the whole path to the root directory of the project (the lib folder I think). When I include I include the absolute path to the hard disk, like this:
代码完美运行。因为我指定了项目根目录的整个路径(我认为是lib文件夹)。当我包含时,我包含了硬盘的绝对路径,如下所示:
require "#{File.dirname(__FILE__)}/shape"
require "#{File.dirname(__FILE__)}/rectangle"
require "#{File.dirname(__FILE__)}/square"
It's also working perfectly.
它也工作得很好。
So, I just want some explanation if know why the first import method (the relative path to the current folder) in not working.
所以,如果知道为什么第一个导入方法(当前文件夹的相对路径)不起作用,我只想解释一下。
回答by nacyot
Relative path is based on working dir. I assume that there is main file on the same directory. If you run ruby ./shapes/main.rbon project root, ruby try to find {project_root}/shape.rb, not {project_root}/shapes/shape.rb. It doesn't work.
相对路径基于工作目录。我假设在同一目录中有主文件。如果您ruby ./shapes/main.rb在项目根目录上运行,ruby 会尝试查找{project_root}/shape.rb,而不是{project_root}/shapes/shape.rb. 它不起作用。
You need to use require_relativelike below.
你需要require_relative像下面这样使用。
# {project_root}/shapes/main.rb
require_relative './shape'
require_relative './rectangle'
require_relative './square'
回答by fl00r
You are using relative path. And they are relative to the place where your script is executed. Generally it is bad idea. You should use either absolute path, either relative path to exact file where requireis executed.
您正在使用相对路径。它们与执行脚本的位置有关。一般来说,这是个坏主意。您应该使用绝对路径,或者require是执行的确切文件的相对路径。
require File.expand_path("../shape", __FILE__)
PS: require_relativelooks more laconic
PS:require_relative看起来更简洁
回答by Vaibhav
require(name) → true or false Loads the given name, returning true if successful and false if the feature is already loaded.
require(name) → true 或 false 加载给定的名称,如果成功则返回 true,如果功能已经加载则返回 false。
If the filename does not resolve to an absolute path, it will be searched for in the directories listed in $LOAD_PATH ($:).
如果文件名未解析为绝对路径,则会在 $LOAD_PATH ($:) 中列出的目录中搜索。
If the filename has the extension “.rb”, it is loaded as a source file; if the extension is “.so”, “.o”, or “.dll”, or the default shared library extension on the current platform, Ruby loads the shared library as a Ruby extension. Otherwise, Ruby tries adding “.rb”, “.so”, and so on to the name until found. If the file named cannot be found, a LoadError will be raised.
如果文件名带有“.rb”扩展名,则作为源文件加载;如果扩展名是“.so”、“.o”或“.dll”,或者当前平台上的默认共享库扩展名,Ruby 会将共享库作为 Ruby 扩展名加载。否则,Ruby 会尝试在名称中添加“.rb”、“.so”等,直到找到为止。如果找不到指定的文件,则会引发 LoadError。
For Ruby extensions the filename given may use any shared library extension. For example, on Linux the socket extension is “socket.so” and require 'socket.dll' will load the socket extension.
对于 Ruby 扩展,给定的文件名可以使用任何共享库扩展。例如,在 Linux 上,套接字扩展名为“socket.so”,并且 require 'socket.dll' 将加载套接字扩展。
The absolute path of the loaded file is added to $LOADED_FEATURES ($"). A file will not be loaded again if its path already appears in $". For example, require 'a'; require './a' will not load a.rb again.
加载文件的绝对路径被添加到 $LOADED_FEATURES ($") 中。如果文件的路径已经出现在 $" 中,则不会再次加载该文件。例如,需要 'a'; require './a' 不会再次加载 a.rb。
require "my-library.rb" require "db-driver" Any constants or globals within the loaded source file will be available in the calling program's global namespace. However, local variables will not be propagated to the loading environment.
require "my-library.rb" require "db-driver" 加载的源文件中的任何常量或全局变量都将在调用程序的全局命名空间中可用。但是,局部变量不会传播到加载环境。
require_relative(string) → true or false Ruby tries to load the library named string relative to the requiring file's path. If the file's path cannot be determined a LoadError is raised. If a file is loaded true is returned and false otherwise.
require_relative(string) → true 或 false Ruby 尝试相对于所需文件的路径加载名为 string 的库。如果无法确定文件的路径,则会引发 LoadError。如果加载了文件,则返回 true,否则返回 false。
Ref: http://ruby-doc.org/core-2.1.2/Kernel.html#require-method
参考:http: //ruby-doc.org/core-2.1.2/Kernel.html#require-method

