【发布时间】:2011-05-18 13:36:19
【问题描述】:
require File.expand_path(..., __FILE__) 是在项目中要求其他文件的最佳方式吗?
【问题讨论】:
-
如果可以的话,我会 +100。这是我希望没有的事情。
require File.expand_path(..., __FILE__) 是在项目中要求其他文件的最佳方式吗?
【问题讨论】:
在 Ruby 2.x 中,您可以使用 Kernel#__dir__
【讨论】:
在 Ruby 1.9.2 + require_relative 中可能是更正确的方法。
出于安全原因,require 已更改为不包含您的 '.' 目录。添加require_relative 是为了为相对于您的调用脚本路径的模块提供本地文件解决方案。
您可以search here on StackOverflow,尤其是“What is require_relative in Ruby?”,并在互联网上找到使用技巧,why-for messages 解释它是如何产生的。
【讨论】:
在 Ruby 1.8.x 中,核心中没有 require_relative,File.expand_path(...,__FILE__) 将不起作用。
假设__FILE__ == "/home/yourname/foo.rb"。 File.expand_path("bar.rb",__FILE__) 给了"/home/yourname/foo.rb/bar.rb。
你想要的是File.expand_path("bar.rb",File.dirname(__FILE__)),它返回"/home/yourname/bar.rb"
您也可以从backports gem 获得require_relative。
【讨论】:
require File.expand_path("../baz.rb", __FILE__) 将 foo.rb 中的 baz.rb 包含在同一目录中。
File.expand_path("../../lib/mygem.rb", __FILE__) 是 2.1.0 文档中为 expand_path 提供的一个实际示例。但这涉及假装一个非目录是一个目录,然后移动到它假定的父目录!我很困惑官方文档会推荐这种不正常的方法,我想知道它是否只能通过实现的一些脆弱的副作用起作用,这可能会改变未来版本的行为。我认为dirname 方法更干净。
除非您修改 $LOAD_PATH,如果您继续从相同的目录结构加载,这将是一个好主意,否则您将无法这样做。
为了确保事情尽可能跨平台,我采取的方式是这样的:
require File.expand_path(File.join(*%w[ ... ]), File.dirname(__FILE__))
这有点冗长,但在大多数情况下,它会产生最短的路径和最少的语法错误。
一个更具体的例子是:
require File.expand_path(File.join(*%w[ .. lib example ]), File.dirname(__FILE__))
如果您要加载大量文件并执行此操作,您可以将其与对 $LOAD_PATH 的修改相结合以简化操作:
$LOAD_PATH << File.expand_path(File.join(*%w[ .. lib ]), File.dirname(__FILE__))
require 'example'
【讨论】: